Home > Software design >  awk - A single f==2 file number to replace two strings in the same file using second and third line
awk - A single f==2 file number to replace two strings in the same file using second and third line

Time:11-15

I'm reading about sub() here in this AWK User's Guide.

I would like to replace two strings in dog.txt, cat and sun, both respectively using the content of the second and third line of the anti-dog-sun.txt file.

dog.txt:

school
dog
sun

anti-dog-sun.txt:

house
cat
moon

First I would like to submit how I can replace the string dog of dog.txt using the second line of anti-dog-sun.txt, ie, replace dog with cat on the dog.txt and save output to 2.txt, as follows below:

code_0:

awk \
'FNR==1 {  f}
f==1 {a[i  ]=$0}
f==2 {if (sub(/dog/,a[int((h  )%(0.5*2)/1) 1])) ; print > "1.txt"}' \
anti-dog-sun.txt dog.txt

output 1.txt:

school
cat
sun

Now to be able to replace the string sun of dog.txt by using the third line of anti-dog-sun.txt,ie replace sun with moon, and save output to 2.txt, I used the following:

code_01:

  awk \
  'FNR==1 {  f}
  f==1 {a[i  ]=$0}
  f==2 {if (sub(/sun/,a[int((h  )%(0.5*2)/1) 2 ])) ; print > "2.txt"}' \
  anti-dog-sun.txt dog.txt

output 2.txt:

school
dog
moon

But I would not like to make these two replacements and save at 1.txt and 2.txt separately.

I would like to make the two replacements in a single process f==2 {if(sub(); print > "single.txt"}, ie save only in single.txt, where single.txt at the end would like this:

school
cat
moon

I tried somehow ..sub(/dog//sun/,a[int((h )%(0.5*2)/1) 1],a[int((j )%(0.5*2)/1) 2]).. to join the code_0 and code_01 in only code_02 below:

awk \
'FNR==1 {  f}
f==1 {a[i  ]=$0}
f==2 {if (sub(/dog/,/sun/,a[int((h  )%(0.5*2)/1) 1],a[int((j  )%(0.5*2)/1) 2])) ; print > "single.txt"}' \
anti-dog-sun.txt dog.txt

But get follow error:

awk: cmd. line:3: f==2 {if (sub(/dog/,/sun/,a[int((h  )%(0.5*2)/1) 1],a[int((j  )%(0.5*2)/1) 2])) ; print > "single.txt"}
awk: cmd. line:3:                                                                              ^ 4 is invalid as number of arguments for sub

Note: Before posting this question I read the guide AWK User Guide several times and I also tried to seek some answer here in the OS or out of it, and I'm not sure if it is possible to make these two replacements using only a sub().

EDIT UPDATE: If you really can not perform the 2 replacements using sub() once time is there any way to do this without writing more than once in the single.txt file? A solution that is portable? An answer that satisfies my edit UPDATE 02.

EDIT UPDATE 01: I do not want to simply replace the second and third line of dog.txt respectively using the second and third line of anti-dog-sun.txt (this is only to display an MWE), if the solution should look for the strings dog and sun.

EDIT UPDATE 02: Another condition is that the mechanism a[int((k )%(x3*2)/x2) x1] should be maintained because this MWE emerged from a real use of the answer of this issue here awk - Replace each X nth occurs from anything between two strings in Different files using line range from another file.

EDIT UPDATE 03: There was a typing error while I made edits of my question I already corrected dog.txt anti-dog-sun.txt to anti-dog-sun.txt dog.txt. Sorry.

CodePudding user response:

Assuming you want to perform the replacement based of the contents, would you please try:

awk 'NR==FNR {a[FNR]=$0; next}          # store the lines of anti-dog-sun.txt in the array "a"
    /dog|sun/ {$0=a[FNR]} 1             # replace the lines of dog.txt if the keyword matches
' anti-dog-sun.txt dog.txt

CodePudding user response:

You can use head and tail:

head -n1 dog.txt; tail -n2 anti-dog.txt
school
cat
moon

Or with awk:

awk '(FNR==NR && NR==1) || (NR>FNR && FNR>1)' dog.txt anti-dog.txt
# same

CodePudding user response:

Solved:

awk \
'FNR==1 {  f}
f==1 {a[i  ]=$0}
f==2 {sub(/dog/,a[int((h  )%(0.5*2)/1) 1]); sub(/sun/,a[int((j  )%(0.5*2)/1) 2]) ; print > "single.txt"}' \
anti-dog-sun.txt dog.txt

single.txt:

school
cat
moon

delete if, put each substitution in a single sub(), separate each sub() by ; and then print single.txt.

Related: Replacing two strings using awk.

  • Related