特定の文字列を含む行のみをsedする方法は?


13

入力:

Select ASDF 325 sdfg sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg sdfg 4456 sdrg

出力:

Select ASDF 325 XXXX sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg XXXX 4456 sdrg

要するに、「sed」「sdfg」を「XXXX」にする必要があります。

ただし、「Select ASDF」文字列を含む行のみ。これを行うにはどうすればよいですか?(sed、awkなど:\)

回答:


19

ほとんどのsedコマンドの先頭にアドレスを付けて、適用する行を制限できます。アドレスは、行番号、またはで区切られた正規表現/です。

cat INPUT | sed '/Select ASDF/ s=sdfg=XXXX='

Peter.Oで述べたように、上記のコマンドsdfgは、を含む文字列内のanyの最初の出現を置き換えますSelect ASDFsdfg4番目の列にある場合にのみ完全一致を置換する必要がある場合は、次のようにします。

cat INPUT | sed 's/\(^Select ASDF [^ ]* \)sdfg /\1XXXX /'

1
sdfgを含む別のフィールドはどうですか?例えば。5sdfga
Peter.O

うーん、実際にはそれも問題ではありません。回答を更新しました。
ラッシュ

使用するためのオプションがあります:sed '/ Select ASDF / gs = sdfg = XXXX ='-したがって、最初の行だけでなく、行のすべての行を置き換える必要があります。ただし、「g」を使用するとsedでエラーが発生する
-LanceBaynes

1
g最後の後に=sコマンドの最後に)入力する必要があります。次のようになりますsed '/Select ASDF/ s=sdfg=XXXX=g'
急ぎます

7

列4の値が正確である場合にのみ列4を変更する場合は、正規表現の代わりに等値演算子を使用するのが理にかなっています。

awk '$1 == "Select" && $2 == "ASDF" && $4 == "sdfg" {$4 = "XXXX"} {print}'

1
速い!.. BireiのAWKとラッシュので、100万行のために、それを比較する位置のsed: 0m1.580s0m3.792s0m6.740s
Peter.O

1

を使用してGNU awk

awk '
    BEGIN { IGNORECASE = 1 } 
    /^select asdf/ { 
        sub( /\<sdfg\>/, "XXXX", $0 ) 
    } 
    { print }
' infile

出力:

Select ASDF 325 XXXX sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg XXXX 4456 sdrg

UPDATEIGNORECASE非GNUを避け、awk大文字と小文字を区別して一致させます。その詳細を指摘してくれたjw013に感謝します。

awk ' 
    /^Select ASDF/ { 
        sub( /\<sdfg\>/, "XXXX", $0 ) 
    } 
    { print }
' infile

1
あなたは言及する必要IGNORECASEがありますGNU awk/ gawk拡張機能です。
jw013

1
@ jw013:ありがとう。あなたの提案で答えを更新しました。
-Birei

4
この場合、IGNORECASEはGNUでもG'notでも間違っています。質問の基準は明示的に大文字ASDF
です-Peter.O
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.