Modify text file if found multiple pattern match for every line.

Looking for help,

i have input file like below and want to modify to expected output, if can without create additional file, hope can direct modify it.

have 2 thing need do.
1st
is adding a word (testplan generation off) after ! ! IPG: Tue Aug 07 14:31:17 2018
2nd
is adding (permanent) word with few type condition
few pattern , some need with ; some need with , .

Input file

! IPG: Tue Aug 07 14:31:17 2018

test capacitor "c13"; characterize, comment
test capacitor "c297"; characterize
test capacitor "c24"; nulltest !tested in parallel with c20
test pins "pins"
test capacitor ".discharge"

expected output

! IPG: Tue Aug 07 14:31:17 2018

testplan generation off

test capacitor "c13"; permanent, characterize, comment
test capacitor "c297"; permanent,  characterize
test capacitor "c24"; permanent,  nulltest !tested in parallel with c20
test pins "pins"; permanent
test capacitor ".discharge"; permanent

Any attempts / ideas / thoughts from your side?

In addition to what RudiC has already asked, what operating system and shell are you using?

for the 1st i'm try is search for ! IPG ,but it add all my file might have multiple same pattern , i'm only need add after 1st found.

for the 2nd 1, im only have some idea is search for 2nd " and add ; permanent if can't find ; after it, if not add after
permanent, after ;.
but this i'm got no idea how to write a code.

OS: window xp 7 and 10.
shell : kornshell

Try

sed -e '0,/! IPG:/{/! IPG:/a\
\
testplan generation off' -e '; }; /! IPG:/ b; s/;/; permanent,/; t; /^ *$/!s/$/; permanent/' file

Hi Rubic,

it fail error:

sed: lebel "; s/;/; permanent,/; t; /^ *$/!s/$/; permanent/" not found in script

if can please help split it to two line, so i can more understand about the code, i want learn some too.

What OS, shell (as already asked by Don Cragun), and sed version do you use?

My sed 's man page says:

What does your's say?

OS: window xp, 7 and 10.
shell :MKS kornshell

sed version , i trying sed --version it not work.

i means the 2 request i'm asking if can split it to 2 difference code line.

From mkssoftware.com:

, so the script should work as given unless something weird happened when copying it. Try to add a space between b and ; .
Your request to split can't be satisfied that easy as the two are interwoven.

Here is a multi-line sed script that does substitutions in the first ! IPG block only.

sed '
  /^! IPG: /{
    a\
\
testplan generation off
    :Loop
    n
    /^! IPG: /b
    /; permanent/bLoop
    /^ *$/bLoop
    s/; /&permanent, /
    tLoop
    s/$/; permanent/
    bLoop
  }
' file

The Unix sed has some shortcomings:

  1. The "label parser" treats a semicolon and trailing spaces as part of the label. A newline is a must. The man page only mentions the maximum length of 7 (or 8) characters.
  2. Before and after a } there must be a semicolon or newline. In some Unix sed versions a semicolon can lead to a wrong behavior; only the newlines are safe, i.e. place the } on a dedicated line. On some systems the man page says "only newlines allowed".
  3. An addtional -e is like a newline. So you can have -e '...;:label' -e '...' and -e '...' -e '}' -e '...'

Thank for reply, below is the output i get.
-testplan generation off is show at every line when it meet IPG, can it just show at 1st meet only?
permenent are not added , it only add after 2nd IPG meet, and it add to board 3 to 3 , can it just add if found "?
-and it not modify the file directly, i need to > to other file name, instate of using same file name.

!!!!   14    0    1 1533623476   0000                                         
! IPG: Tue Aug 07 14:31:17 2018

testplan generation off
! IPG: board type 00851-1712
boards 2 to 2
test shorts "shorts"
test capacitor "c488"; nulltest !tested in parallel with c480
test capacitor "c588"; nulltest !tested in parallel with c480
test analog powered "sp-p6"; comment
test digital "u423"
! IPG: board type 00851-1715

testplan generation off
boards 3 to 3; permanent
test shorts "shorts"; permanent
test capacitor "c590"; permanent
test capacitor "c591"; permanent, nulltest !tested in parallel with c590
test analog powered "bp-test"; permanent, comment

! IPG: board type 00860-0106
boards 1 to 1
test shorts "shorts"
test pins "pins"
test capacitor ".discharge"
test capacitor "c102"
test analog powered "u511%opamp_o_1"

Did you try to apply the insight that MadeInGermany gave to the proposal in post#5?

In my attempt to substitute only in the first ! IPG block I have not seen that the whole thing repeats with every 2nd ! IPG .
Because you seem to want substitutions in all blocks anyway, you can simply change the b (leave the loop) to bLoop (continue the loop):

    /^! IPG: /bLoop

Hi Rubic,

i'm trying search web on it , but still unable to future to understand,

testplan generation off
! IPG: board type 00851-1712
boards 2 to 2; permanent
test shorts "shorts"; permanent
test pins "pins"; permanent

this still come out.

Thank alot.

sorry that im 0 knowledge on, i trying to figure up what happen on it but unable to found it.

The s/ / / do the substitutions.
If you want to not have substitions for a certain string, then branch to the Loop before, i.e. have another line

    /boards /bLoop

(If boards is found then branch to Loop.)
If everything looks okay, then redirect the output to a file. And if successful, copy it back to the original file.

sed '
...
' file > file.new &&
cp file.new file &&
rm file.new

The && chain the next command only if the preceding command was successful (exit 0).

1 Like

Try

sed -e '0,/! IPG:/{/! IPG:/a\
\

testplan generation off' -e '; }; /! IPG:/ b;' -e 's/;/; permanent,/; t;' -e '/^ *$/!s/$/; permanent/' file
1 Like
cp testorder testorder_ori

sed '
  /^! IPG: /{
    a\
\
testplan generation off
    :Loop
    n
    /^boards /bLoop
    /^! IPG: /bLoop
    /; permanent/bLoop
    /^ *$/bLoop
    s/; /&permanent, /
    tLoop
    s/$/; permanent/
    bLoop
  }
' testorder_ori >testorder

above is the code that able to work, thank a lot.