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
代わりに使用できますtac
(tail(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段階のアプローチを使用するため、パターンに一致する連続行の問題はありません(テキストを最初に読み取るときに行を削除する代わりに)。