file_a.txtというテキストファイルがあります。私の最初のコマンドは
grep -A 12 ".production =" file_a.txt
出力は複数のブロックです。各文字列ブロックには13行が含まれています。
grep
具体的には、元のファイルfile_a.txtからコマンドを使用して取得したすべての文字列ブロックを削除したいと思います。 grep出力を新しいファイルに送信したくありません。grep -v
私の場合はうまくいかないので、どちらかを使用したくありません。
同様のことを試しましたが、何も機能しません。
cut < grep -A 12 ".production =" file_a.txt
sed -i '/`grep -A 12 ".production ="`/d' file_a.txt
答え1
GNU sedモード
(一部のLinuxディストリビューションを使用している場合はデフォルトの実装でGNU sed
ある必要がありますsed
)次のように使用できます。
sed '/.production =/,+12d' inputfile.txt
仕組み:
- 入力ファイルを1行ずつスキャンし(sedが機能する方法)、コマンドを使用する必要があるかどうかを確認します。
- 私たちのコマンドは
d
(最後の文字)です。これは行削除を意味します。 - ただし、このコマンドは現在の行が範囲と一致する場合にのみ実行されます。
- 範囲は、範囲の始まりと終わりを含む文字で区切られた2つのパラメーターで指定されます
,
。 1つ目は、/.production =/
式を含むすべての行に一致する正規表現です。 2番目のパラメータ+12d
はを意味します12 lines from start range
。 - したがって、範囲は式に一致するすべての行と次の12行を一致させて削除します。
- 他のすべての行は出力として印刷されます(デフォルト
sed behaviour
)。
ポータブル、醜い方法
これは他のsed
実装と連携する必要がありますが、より多くの入力が必要で強力ではありません。
sed '/.production =/{N;N;N;N;N;N;N;N;N;N;N;N;d}' somefile.txt
仕組み:
- 入力ファイルを1行ずつスキャンし(sedが機能する方法)、コマンドを使用する必要があるかどうかを確認します。
/.production =/
線がパターンと一致していることを確認してください。その場合は、中かっこで囲まれたすべてのコマンドを実行します{}
。- 私たちは
N
コマンドを12回実行しました。N
このコマンドは次の行を読み取り、それを現在のバッファに追加します。したがって、12回実行した後、13行が現在バッファに接続されます(最初の行+N
コマンドで読み取られた12行)。 d
次に、リンクされている13行を削除するコマンドを実行します。sed
別のパターンが見つかるまで続行し、13行目をもう一度削除します。他のすべての行は印刷されます(デフォルトのsed
動作)。
答え2
フィルタリングを開始したい行番号を検索し、AWKを使用してフィルタリングできます。
AWKでは、NRはレコード番号を表し、デフォルトは行末(\ n)です。
START_LINE=$(cat file_a.txt | grep -n .production | cut -f1 -d:)
cat file_a.txt | awk '{ if(NR < '$START_LINE' || NR > '$START_LINE' + 12) print $0; }'
答え3
grepとsedで問題を完全に解決できない場合は、awkを使用できます。 awkはほとんどのテキストユーティリティを簡単にエミュレートできます(sort
これは主な例外です)、パイプよりも柔軟な方法で組み合わせることができます。
awk '
/.production =/ {skip_lines = 13}
skip_lines {--skip_lines}
!skip_lines {print}
' file_a.txt >file_a.txt.new &&
mv file_a.txt.new file_a.txt
答え4
ExモードでVimを使用できます。
ex -sc '/.production =/d13|x' file_a.txt
//
一致する行に移動13
13行目を選択してください。d
削除x
保存して閉じる