一致と前の行を除くすべてをgrepする方法

一致と前の行を除くすべてをgrepする方法

grepが一致しないようにしたいテキストファイルとパターンがあります。問題は、前の行も一致しないようにしたいということです。

私のファイル:

line 1
line 2
pattern
line 4

私はそれを試しました、cat file | grep -v pattern結果は次のようになります。

line 1
line 2
line 4

それから試してみましたが、cat file | grep -B 1 pattern結果は次のとおりです。

line 2
pattern

ただし、一緒に使用すると、次のような結果がcat file | grep -v -B 1 pattern得られます。

line 2

出力をどのように作成できますか?

line 1
line 4

ベストアンサー1

私はgrepファイルから1行を抽出するときにのみこのツールを使用する傾向があるため、テキストでより複雑な編集を実行する必要がある場合は別のツールを使用します。

ここのすべての解決策は、パターンがテキスト内で複数回表示されることを前提としており、パターンが発生する行と直前の行を削除します。最初の2つの解決策は、パターンが連続した行で一致する場合に問題が発生します。


sedパターンを一致させ、/pattern/コマンドNとをトリガーすることができますd。このコマンドは、次の行をバッファに追加し、両方を削除します。

sed '/pattern/ { N; d; }' file

なぜなら、あなたはその行を捨てたいからです今後パターンを一致させるためにデータを逆に入力しますsed。最後の行から始めてファイルの先頭に移動します。sed完了したら、データを再び反転します。

tac file | sed '/pattern/ { N; d; }' | tac

このtacユーティリティはGNU coreutilsの一部です。ほとんどの非GNUシステムをtail -r代わりに使用できますtactail(1)マニュアルを確認してください)。

パターンが 2 つの連続した行と一致する場合、最初の行が削除されるため、最初の行より前の行は削除されません。


edエディタを使用してください。

printf '%s\n' 'g/pattern/ -1,. d' ,p Q | ed -s file

g/pattern/ -1,. dこれにより、ファイルの内容にコマンドが適用されます。このコマンドは、一致する各行を検索し、その行patternとその前の行を削除します。

最終,p編集Qコマンドは、ファイル全体を印刷して保存せずにエディタを終了します。

パターンが2つの連続した行と一致する場合は、最初の行の前の行を削除してから、2番目の行の前の行を削除します。

(最後の文は正しい文を書いてみると、きっとそのまま書く文章なのが明らかだ。 )


grep非標準ですが一般的に使用される-Bオプションを使用して、削除する必要がある行番号を指定することもできます。この数値は、sed生データで実行されるスクリプトに変換できます。

grep -n -B1 'pattern' file | sed 's/[:-].*/d/' | sed -f /dev/stdin file

grep質問のテキストに基づいてコマンドが出力されます。

2-line 2
3:pattern

...最初のsedコマンドはそれをsed編集コマンドに変換し、2dその後に3d(「2行と3行削除」)が続きます。sedパイプラインの最後のコマンドはこの編集スクリプトを取得し、元のテキストに適用します。

このバリアントは最初に削除する必要があるすべての行を見つけてから削除する2段階のアプローチを使用するため、パターンに一致する連続行の問題はありません(テキストを最初に読み取るときに行を削除する代わりに)。

おすすめ記事