ファイル内で次のシーケンスが複数回発生しています。
yyyy
xxxx
zzzz
に一致する正規表現がありxxxx
ます。yyyy
一致するものがあるときはいつでも、その行、前の行 (eg ) とその後の行(eg )を削除したいと考えていzzzz
ます。sed を使用してこれを行うにはどうすればよいですか?
トリックは、「保留スペース」に表示された最後の行を保存することです。
sed -n '
/^xxxx/{n
n
x
d
}
x
1d
p
${x
p
}
' <input file>
-から開始してx
、現在の入力行をホールド スペースと交換し ( x
)、最初の行では何も出力せず ( 1d
)、後続の行ではホールド スペースからスワップしたばかりの行を出力し ( p
)、最後の行でホールドを交換します。もう一度スペースを空けて、そこにあったものを出力します ( $x{x p}
。これで、ターゲット行 (開始) にヒットしたときに何をすべきかが残ります/^xxxx/
- 次の 2 行をパターンスペースに読み込み ( n n
)、パターンスペースをホールドスペースと交換します ( x
) - これにより、印刷したい次の行のホールド スペースと、マッチの前の行のパターン スペースは不要なので、破棄します ( d
)
これは私がperlで行う方法です。おそらく、正しい軌道に乗るのに役立つでしょう...頑張ってください!
open(INFILE,"<in.txt");
my(@arrayOutBoundData, $skipNextLine)l
for (<INFILE>) {
if (not $skipNextLine) {
if (/^xxxx$/) {
pop(@arrayOutBoundData);
$skipNextLine = 1;
} else {
push(@arrayOutBoundData,$_);
}
}
$skipNextLine = 0
}
open(OUTFILE,">out.txt");
for (@arrayOutBoundData) {
print OUTFILE;
}
(このシステムでは perl はテストされていません。オーバーサイトはご容赦ください。)
このドキュメントをチェックアウトできます。sed
複数の行を操作するための使用について説明します。
これはうまくいくかもしれません(GNU sed):
echo -e "a\nyyyy\nxxxx\nzzzz\nb" | sed 'N;/^xxxx/M{/^xxxx/d;$!N;d};P;D'
a
b
これにより、パターン空間に 2 行のウィンドウが保持され、必要な正規表現が 1 行目または 2 行目に見つかった場合、次の行が読み取られ、3 行すべてが削除されます。エッジケースは、正規表現が最初または最後の行で見つかった場合で、前後に行がない場合です。この場合、削除できるのは 2 行だけです。
ちなみに、この解決策により、GNU sed の潜在的なバグが発見された可能性があります。M
アドレスのフラグを使用すると、複数行の文字列の行頭と行末の正規表現で長さゼロのマーカーとしてメタ文字^
とメタ文字を使用できます。$
空のアドレス//
は、以前に指定されたアドレスを再利用します。そのアドレスは、複数行フラグを含むアドレスにする必要がありますか? 現在、フラグが記載されていなくてもフラグが含まれているようです。
sed 'N;/^xxxx/M{/^xxxx/d;$!N;d};P;D' file
次の場合とは異なる (正しい) 結果が生成されます。
sed 'N;/^xxxx/M{//d;$!N;d};P;D' file
xxxx
ファイルの 2 行目にある場合。
以下を使用できます。
sed -n '/xxxx/{N;s/.*//;x;d;};x;p;${x;p;}'
これにより、3 行が 1 行の空白行に置き換えられます。
grep -v -f <(grep -1 "xxxx" file) file