私はこれを使用します
cat foo.txt | sed '/bar/d'
bar
ファイル内の文字列を含む行を削除します。
ただし、これらの行とその直後の行を削除します。好ましくでsed
、awk
またはMINGW32で利用できる他のツール。
それは私が得ることができるものの逆のようなものだgrep
と-A
し、-B
マッチした行の前/後に一致した行だけでなく、ラインを印刷します。
それを達成する簡単な方法はありますか?
私はこれを使用します
cat foo.txt | sed '/bar/d'
bar
ファイル内の文字列を含む行を削除します。
ただし、これらの行とその直後の行を削除します。好ましくでsed
、awk
またはMINGW32で利用できる他のツール。
それは私が得ることができるものの逆のようなものだgrep
と-A
し、-B
マッチした行の前/後に一致した行だけでなく、ラインを印刷します。
それを達成する簡単な方法はありますか?
回答:
GNU sed(組み込みLinuxまたはCygwin)を使用している場合:
sed '/bar/,+1 d'
bar
2行連続している場合、2行目は分析せずに削除されます。たとえば、3行のファイルbar
/ bar
/があるfoo
場合、そのfoo
行は残ります。
bar
s がないので、これは覚えやすいです。
sed '/bar/d'
次の行ではなく「特定の文字列を含む行を削除する」だけの場合。
sed '/math/q'
sed '/bar/d'
bar
連続した行で発生する可能性がある場合は、次を実行できます。
awk '/bar/{n=2}; n {n--; next}; 1' < infile > outfile
上記の2行を、一致する行を含めて削除する行数で変更することにより、2行以上を削除するように適合させることができます。
そうでない場合、それは簡単で行うのsed
で@MichaelRollinsのソリューションまたは:
sed '/bar/,/^/d' < infile > outfile
/bar/
と/bar|baz|whatever/
。ではsed
その構文動作するようには思えません。
sed
「拡張」正規表現の使用を要求できます。詳細はこちら:gnu.org/software/sed/manual/html_node/…。これgrep
も同様に適用されることに注意してください。これが私自身の実例です:echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
。
私はsedに堪能ではありませんが、awkでそれを行うのは簡単です:
awk '/bar/{getline;next} 1' foo.txt
awkスクリプトは次のように読み取ります。barを含む行については、次の行を取得し(getline)、その後のすべての処理をスキップします(next)。最後の1パターンは、残りの行を印刷します。
コメントで指摘されているように、上記の解決策は連続して機能しませんでしたbar
。以下は修正されたソリューションであり、それを考慮に入れています。
awk '/bar/ {while (/bar/ && getline>0) ; next} 1' foo.txt
すべての/ bar /行をスキップするために読み続けています。
grep -A
100%を複製するには、任意の数の連続するbar
行を正しく処理する必要もあります(ブロック全体とその後の1行を削除することにより)。
これを実現するには、sedのスクリプト機能を使用する必要があります。
$ sed -e '/bar/ {
$!N
d
}' sample1.txt
サンプルデータ:
$ cat sample1.txt
foo
bar
biz
baz
buz
「N」コマンドは、入力の次の行をパターンスペースに追加します。これは、パターンマッチ(/ bar /)の行と組み合わせて、削除する行になります。その後、「d」コマンドを使用して通常どおりに削除できます。
sed -e '/bar/{N;d}' sample1.txt
一致の直後の行を削除する必要がある場合、sed
プログラムは連続した一致を考慮する必要があります。つまり、一致する一致の後に続く行を削除する場合は、おそらくその後の行も削除する必要があります。
簡単に実装できますが、少し後を見る必要があります。
printf %s\\n 0 match 2 match match \
5 6 match match match \
10 11 12 match 14 15 |
sed -ne'x;/match/!{g;//!p;}'
0
6
11
12
15
読み込まれた各行のホールドスペースとパターンスペースを交換することで機能します。そのため、毎回最後の行を現在の行と比較できます。したがってsed
、行を読み取ると、そのバッファーの内容が交換されます。その場合、前の行は編集バッファーの内容になり、現在の行は保留スペースに入れられます。
そのsed
ため、前の行でと一致するかどうかを確認し、見つからないmatch
場合!
は{
関数内の2つの式}
が実行されます。sed
意志g
現在のラインが保留とパターンスペースの両方に続いている意味- -そしてそれはなりパターンスペース上書きしらホールドスペース//
の最も最近コンパイルされた正規表現にマッチしていないか確認を- match
-そしてもしそれがないmatch
ことをさp
rinted。
これは、そうでない場合は行のみが印刷されることを意味し、直前の行にはありません。また、esのシーケンスの不必要なスワップも無視します。match
match
match
あとで発生する任意の行数を削除できるバージョンmatch
が必要な場合は、もう少し作業が必要になります。
printf %s\\n 1 2 3 4 match \
match match 8 \
9 10 11 12 13 \
14 match match \
17 18 19 20 21 |
sed -net -e'/match/{h;n;//h;//!H;G;s/\n/&/5;D;}' -ep
... 5を、削除する行数(一致した行を含む)に置き換えます...
1
2
3
4
12
13
14
21