
あるファイルのパターンに一致する行を、別のファイルの行に順番に置き換えたいとします。たとえば、次のようになります。
ファイル1.txt:
aaaaaa
bbbbbb
!! 1234
!! 4567
ccccc
ddddd
!! 1111
!! で始まる行を次のファイルの行に置き換えます。
ファイル2.txt:
first line
second line
third line
結果は次のようになります。
aaaaaa
bbbbbb
first line
second line
ccccc
ddddd
third line
答え1
簡単にできる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
答え2
と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
とperl
$ < file2.txt perl -pe '$_ = <STDIN> if /^!!/' file1.txt
aaaaaa
bbbbbb
first line
second line
ccccc
ddddd
third line
- 置き換えた行を標準入力としてファイルを渡し、
<STDIN>
ファイルハンドルを使用して読み取ることができるようにする - 一致する行が見つかった場合は、
$_
標準入力からの行に置き換えます