私はこれを使う
cat foo.txt | sed '/bar/d'
bar
この文字列を含むファイルの行を削除します。
しかし、この行を削除したいです。そしてすぐ次の行。 MinGW32で利用可能な他のツールを使用することsed
をお勧めします。awk
これは、一致する行と一致する行の前後の行をgrep
印刷できる場所とは反対です。-A
-B
これを達成する簡単な方法はありますか?
答え1
GNU sed(組み込みのLinuxまたはCygwin)がある場合:
sed '/bar/,+1 d'
bar
行に2つの行がある場合は、2番目の行を解析せずに削除します。たとえば、bar
// 3行のファイルがある場合、その行bar
はfoo
保持foo
されます。
答え2
bar
連続した行に表示できる場合は、次のようにできます。
awk '/bar/{n=2}; n {n--; next}; 1' < infile > outfile
上記の2を削除する行数(一致する行を含む)に変更して2つ以上の行を削除する場合に適用できます。
そうでなければ簡単にsed
できます@MichaelRollinsのソリューションまたは:
sed '/bar/,/^/d' < infile > outfile
答え3
私はsedにあまり慣れていませんが、awkではこれを簡単に実行できます。
awk '/bar/{getline;next} 1' foo.txt
awkスクリプトの内容は次のとおりです。 barを含む行に対して次の行を取得し、その後のすべての処理をスキップします。最後の1パターンは残りの行を印刷します。
修正する
コメントで指摘したように、上記のソリューションは隣接するソリューションでは機能しませんbar
。以下は、これを考慮した修正ソリューションです。
awk '/bar/ {while (/bar/ && getline>0) ; next} 1' foo.txt
それでは、すべての/bar/行をスキップして読み続けます。
答え4
一致のすぐ次の行を削除する必要がある場合は、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
1行を読み取ると、対応するバッファの内容が置き換えられます。前の行は編集バッファーの内容で、現在の行は予約済みスペースに配置されます。
sed
前の行に一致するものがあることを確認してください。match
、見つからない場合は、関数!
で両方の式を実行します。パターンスペースを上書きして予約済みスペースを設定します。つまり、現在の行は予約済みスペースとパターンスペースの両方にあります。次に、最後にコンパイルされた正規表現と一致することを確認します。{
}
sed
g
//
match
- もしそれ確かにmatch
印刷されましたp
。
これは、行が存在しない場合にのみ印刷されることを意味します。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