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

2 Answers 2

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
2
  • Simpler than my awk attempt :)
    – ilkkachu
    Oct 15, 2016 at 10:58
  • 1
    Costas, +1 but consider adding some explanation for future readers.
    – heemayl
    Oct 15, 2016 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .