次のファイルがあります。
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211
3;1471383211;frank;WO12345;1471385211
4;1471385311;frank;WO12345;
5;1471385311;joe;WO12346;1471388211
frank
bashスクリプトを使用して、指定された名前(例:)と指定されたWO番号(例WO12345
:)を含め、次に終わる行を見つけ、行末に;
文字列を追加したいと思います。 stdoutに出力するのではなく、ファイルを直接編集したいと思います。read
名前とWO番号を取得する方法を知っています。私はsed
with-i
が正しいツールだと思います。どうすればいいですか?
答え1
名前とWOが常に連続であれば簡単です。
sed '/frank;WO12345;/s/;$/;sometext/' -i file
何らかの方法で表示される場合や必ずしも互いに隣り合う必要はない場合は、コマンドブロックを使用して両方のテストを組み合わせます。
sed '/;frank;/{/;WO12345;/s/;$/;sometext/}' -i file
答え2
awk
フィールドで区切られたデータに適しています。
使用awk
:
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
;Foobar
最後に挿入したい項目に置き換えます。
ここでは、分離された3番目と4番目のフィールドが必須文字列と一致することを確認し;
、そうで;Foobar
あれば最後に文字列を追加します。
最新のGNU awk
(> = 4.10)には内部編集オプションがあります。
awk -i inplace -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
sponge
GNUmoreutils
または一時ファイルの機能を使用しない場合:
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt | sponge file.txt
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' \
file.txt >file_temp.txt && mv file_temp.txt file.txt
あなたが主張している場合sed
:
sed -Ei '/^([^;]*;){2}frank;WO12345;/ s/$/;Foobar/' file.txt
([^;]*;){2}
最初の 2 つのフィールドと一致し、3 番目と 4 番目のフィールドが必須であることを確認し、交換を完了します。
例:
$ cat file.txt
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211
3;1471383211;frank;WO12345;1471385211
4;1471385311;frank;WO12345;
5;1471385311;joe;WO12346;1471388211
$ awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
2;1471378551;frank;WO12345;1471380211;Foobar
3;1471383211;frank;WO12345;1471385211;Foobar
4;1471385311;frank;WO12345;;Foobar
$ sed -E '/^([^;]*;){2}frank;WO12345;/ s/$/;Foobar/' file.txt
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211;Foobar
3;1471383211;frank;WO12345;1471385211;Foobar
4;1471385311;frank;WO12345;;Foobar
5;1471385311;joe;WO12346;1471388211