回答:
これでやってみます。
パターンの後の5行を削除するには(パターンのある行を含む):
sed -e '/pattern/,+5d' file.txt
パターンの後ろの5行を削除するには(パターンのある行を除く):
sed -e '/pattern/{n;N;N;N;N;d}' file.txt
/pattern/,+5は、「パターン」を含む行で始まり(/pattern/)、5行後に終了する()範囲を定義します+5。最後の文字dは、その範囲の各行で実行するコマンド、つまり「削除」です。代わりに範囲を一致させる第二のレシピでは、それは(パターンを含むだけ行に一致し/pattern/)、次いで、一連のコマンド実行:{n;N;N;N;N;d}、基本的に次の行を(プリントn)した後、読み出し、最終的に次の4つのライン(廃棄N;N;N;N;d)。
sed -e '/pattern/{n;N;N;N;N;d;}' file.txt
something実行しますsed -E '/^something$/,$d'。ここで、-EPOSIXの移植は、正規表現を拡張しています。
シンプルなawkソリューション:
一致する行の検索に使用する正規表現がシェル変数$regexに格納され、スキップする行の数が格納されていると仮定し$countます。
一致する行もスキップする必要がある場合($count + 1行はスキップされます):
... | awk -v regex="$regex" -v count="$count" \
'$0 ~ regex { skip=count; next } --skip >= 0 { next } 1'
場合、一致する行がべきではないスキップされ($count行後のマッチはスキップされます)。
... | awk -v regex="$regex" -v count="$count" \
'$0 ~ regex { skip=count; print; next } --skip >= 0 { next } 1'
説明:
-v regex="$regex" -v count="$count"同じ名前のシェル変数にawk基づいて変数を定義します。$0 ~ regex 対象ラインに一致
{ skip=count; next }スキップカウントを初期化して次の行に進み、一致する行を効果的にスキップします。2番目のソリューションでは、printbefore nextはそれがスキップされないようにします。--skip >= 0 (まだ)> = 0の場合、スキップカウントをデクリメントしてアクションを実行し、手元の行をスキップする必要があることを意味します。{ next } 次の行に進み、効果的に現在の行をスキップします1は、の一般的な省略形です{ print }。つまり、現在の行が単に印刷されます
1と同等であるが{ print }それはある1定義によって常に(ブロック)は、その関連付けられたアクションが無条件に実行されることをその手段、真と評価されていることを示すブールパターンとして解釈されます。この場合、関連付けられたアクションがないため、awkデフォルトでは行を印刷します。これはあなたのために働くかもしれません:
cat <<! >pattern_number.txt
> 5 3
> 10 1
> 15 5
> !
sed 's|\(\S*\) \(\S*\)|/\1/,+\2{//!d}|' pattern_number.txt |
sed -f - <(seq 21)
1
2
3
4
5
9
10
12
13
14
15
21
pattern_number.txt1列目に一致するパターンを含む2列のファイルで、2列目にはスキップする行数。最初のsedコマンドsedは、対応するマッチングとスキップを実行するスクリプトにファイルを変換します。このスクリプトは-f、stdin(-)を介して2番目のsedコマンドに提供されます。2番目のsedコマンドは、の出力から形成されたサンプルのアドホック入力ファイルを操作して、seq 21それが機能することを示します。
Perlの使用
$ cat delete_5lines.txt
1
2
3
4
5 hello
6
7
8
9
10
11 hai
$ perl -ne ' BEGIN{$y=1} $y=$. if /hello/ ; print if $y==1 or $.-$y > 5 ' delete_5lines.txt
1
2
3
4
11 hai
$
このソリューションでは、パラメーターとして「n」を渡すことができ、ファイルからパターンを読み取ります。
awk -v n=5 '
NR == FNR {pattern[$0]; next}
{
for (patt in pattern) {
if ($0 ~ patt) {
print # remove if you want to exclude a matched line
for (i=0; i<n; i++) getline
next
}
}
print
}
' file.with.patterns -
「-」という名前のファイルはawkの標準入力を意味するため、これはパイプラインに適しています
+NパターンはGNU拡張機能であることに注意してください。最初の変更nにはN、それは、パターンの行を含める作るためにあなたの第二の例では。