4

I want to replace the lines matching a pattern from one file from the lines in order from another file, for example, given:

file1.txt:

aaaaaa
bbbbbb
!! 1234
!! 4567
ccccc
ddddd
!! 1111

we like to replace the lines starting with !! with the lines of this file:

file2.txt:

first line
second line
third line

so the result should be:

aaaaaa
bbbbbb
first line
second line
ccccc
ddddd
third line
10

Easy can be done with awk

awk '
    /^!!/{                    #for line stared with `!!`
        getline <"file2.txt"  #read 1 line from outer file into $0 
    }
    1                         #alias for `print $0`
    ' file1.txt

Other version

awk '
    NR == FNR{         #for lines in first file
        S[NR] = $0     #put line in array `S` with row number as index 
        next           #starts script from the beginning
    }
    /^!!/{             #for line stared with `!!`
        $0=S[++count]  #replace line by corresponded array element
    }
    1                  #alias for `print $0`
    ' file2.txt file1.txt
  • Simpler than my awk attempt :) – ilkkachu Oct 15 '16 at 10:58
  • Costas, +1 but consider adding some explanation for future readers. – heemayl Oct 15 '16 at 15:40
1

With GNU sed, similar to awk+getline

$ sed -e '/^!!/{R file2.txt' -e 'd}' file1.txt
aaaaaa
bbbbbb
first line
second line
ccccc
ddddd
third line
  • R would give a line one at a time
  • order is important, first R and then d


With perl

$ < file2.txt perl -pe '$_ = <STDIN> if /^!!/' file1.txt
aaaaaa
bbbbbb
first line
second line
ccccc
ddddd
third line
  • pass the file with replacing lines as standard input, so that we can read it using <STDIN> filehandle
  • if matching line is found, replace $_ with a line from standard input

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.