web-dev-qa-db-ja.com

パターンに一致する行を別のファイルの行で順番に置き換えます

たとえば、次のように、あるファイルのパターンに一致する行を別のファイルの行から順番に置き換えたいと思います。

file1.txt

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

!!で始まる行を置き換えるのが好きです。このファイルの行で:

file2.txt

first line
second line
third line

したがって、結果は次のようになります。

aaaaaa
bbbbbb
first line
second line
ccccc
ddddd
third line
4
Msegade

簡単にawkで実行できます

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

他のバージョン

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
10
Costas

GNU sedの場合、awk+getlineと同様

$ sed -e '/^!!/{R file2.txt' -e 'd}' file1.txt
aaaaaa
bbbbbb
first line
second line
ccccc
ddddd
third line
  • Rは一度に1行ずつ表示されます
  • 順序は重要です。最初にR、次にdです。


with Perl

$ < file2.txt Perl -pe '$_ = <STDIN> if /^!!/' file1.txt
aaaaaa
bbbbbb
first line
second line
ccccc
ddddd
third line
  • <STDIN> filehandleを使用してファイルを読み取ることができるように、標準入力として行を置き換えてファイルを渡します
  • 一致する行が見つかった場合は、$_を標準入力の行に置き換えます
1
Sundeep