Twitterでそういった処理について見かけたので、やってみた内容を備忘として残しておく。
sedでやる場合
GNU拡張されたsedの場合 -i
で上書きができるので、ただ文字列を挿入するだけであれば以下のようにしてやればいい。
bash
sed -i '1iString' *.txt
shell[root@BS-PUB-CENT7-01 test_dir]# cat a.txt a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# cat b.txt b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 [root@BS-PUB-CENT7-01 test_dir]# [root@BS-PUB-CENT7-01 test_dir]# sed -i '1iString' {a,b}.txt [root@BS-PUB-CENT7-01 test_dir]# [root@BS-PUB-CENT7-01 test_dir]# cat a.txt String a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# cat b.txt String b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20
ただ、これがファイルを読み込むという内容になると一手間必要になる。 一応、sedでは'r FILEPATH'で指定したファイルを読み込むことができるのだけど、これだと指定した行の後ろ(add)への差し込みになってしまう。
shell[root@BS-PUB-CENT7-01 test_dir]# cat add.txt Oh,yeah! xxxxxxx yyyyyyy [root@BS-PUB-CENT7-01 test_dir]# cat a.txt a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# [root@BS-PUB-CENT7-01 test_dir]# sed '1r add.txt' a.txt a01 a02 Oh,yeah! xxxxxxx yyyyyyy a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
といっても、sedでは改行を含んだ状態では処理できないようなので、コマンド置換でただ記述してもうまく動かない。 じゃあどうするのかというと、一度改行を「\n」で表現するように置換してやればいい。insertだと余計な改行が挟まれる場合が多いため、sで行頭を置換することで対処する。
bash
sed -i '1s/^/'$(sed -z 's/\n/\\n/g' FILEPATH)'/g' *.txt
shell[root@BS-PUB-CENT7-01 test_dir]# sed '1s/^/'$(sed -z 's/\n/\\n/g' add.txt)'/g' a.txt Oh,yeah! xxxxxxx yyyyyyy a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# sed -i '1s/^/'$(sed -z 's/\n/\\n/g' add.txt)'/g' {a,b}.txt [root@BS-PUB-CENT7-01 test_dir]# [root@BS-PUB-CENT7-01 test_dir]# cat a.txt Oh,yeah! xxxxxxx yyyyyyy a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# cat b.txt Oh,yeah! xxxxxxx yyyyyyy b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20
catでやる場合
対象が1ファイルであれば、そもそもcatで普通に書いてやれば標準出力で結合させることができる。
bashcat head.txt file.txt
shell[root@BS-PUB-CENT7-01 test_dir]# cat add.txt Oh,yeah! xxxxxxx yyyyyyy [root@BS-PUB-CENT7-01 test_dir]# cat a.txt a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# [root@BS-PUB-CENT7-01 test_dir]# cat add.txt a.txt Oh,yeah! xxxxxxx yyyyyyy a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
ファイルに上書きする場合、ただリダイレクトしたりteeを使って書き込みをすると、先にリダイレクト処理が走ってしまいファイルが空になってしまう。 このため、一時ファイルを使わないのであればプロセス置換を使うか、もしmoreutilsが入っていればspongeを使うといいだろう(前にもこの辺で書いたけど)。
bash
cat head.txt file.txt > >(sleep 0.1;cat > file.txt) #プロセス置換を使う場合
cat head.txt file.txt | sponge file.txt
shell[root@BS-PUB-CENT7-01 test_dir]# cat a.txt a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# cat add.txt a.txt Oh,yeah! xxxxxxx yyyyyyy a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# [root@BS-PUB-CENT7-01 test_dir]# cat add.txt a.txt > >(sleep 0.1;cat > a.txt) [root@BS-PUB-CENT7-01 test_dir]# cat a.txt Oh,yeah! xxxxxxx yyyyyyy a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# [root@BS-PUB-CENT7-01 test_dir]# cat add.txt a.txt | sponge a.txt [root@BS-PUB-CENT7-01 test_dir]# cat a.txt Oh,yeah! xxxxxxx yyyyyyy Oh,yeah! xxxxxxx yyyyyyy a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
これを複数ファイルに対して処理するなら、xargsを使ってやればいいだけだ。
bash
ls -1 *.txt | xargs -I@ bash -c 'cat head.txt @ > >(sleep 0.1;cat > @)'
shell[root@BS-PUB-CENT7-01 test_dir]# cat a.txt a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# cat b.txt b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 [root@BS-PUB-CENT7-01 test_dir]# [root@BS-PUB-CENT7-01 test_dir]# ls -1 {a,b}.txt | xargs -I@ bash -c 'cat add.txt @ > >(sleep 0.1;cat > @)' [root@BS-PUB-CENT7-01 test_dir]# cat a.txt Oh,yeah! xxxxxxx yyyyyyy a01 a02 a03 a04 a05 a06 a07 a08 a09 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 [root@BS-PUB-CENT7-01 test_dir]# cat b.txt Oh,yeah! xxxxxxx yyyyyyy b01 b02 b03 b04 b05 b06 b07 b08 b09 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20