sed を使用して最初に一致する行のみを削除できますか?

sed を使用して最初に一致する行のみを削除できますか?

ファイルtestfile.txtには

pippo=x
pluto=y
1234=z

削除したいのは最初行の一致/^[a-z]\+=/(この例では最初の行)。

次のコマンドを試しましたが、成功しませんでした。

sed   '/^[a-z]\+=/,+0d' testfile.txt

しかし、最初の行が削除されます。

このタスクを を使用して実行する方法はありますかsed?

よろしく

答え1

sedコマンドに関する問題

$ sed '/^[a-z]\+=/,+0d' testfile.txt

スクリプトsedが適用される入力データの行。

(これはGNU拡張です)は+0、スクリプトが以下と同等であることを意味します。

$ sed '/^[a-z]\+=/d' testfile.txt

お気づきのとおり、最初の行と 2 番目の行は削除されます。

ちなみに、あなたは全く同じものを手に入れるでしょう効果を使用します+1が、他の理由によります。dコマンドは、1 行目と 2 行目に個別に適用されるのではなく、最初の行の一致により最初の 2 行に適用されます (つまり、コマンドの範囲はd1 行目とさらに 1 行目、 になります+1)。範囲外であるため、3 行目は削除されません。

GNUsedソリューション

$ sed '0,/^[a-z]\+=/{//d}' testfile.txt

ユーザー @Whitefield が投稿した方法は機能し、かなり優れています (ただし、より POSIX 風にしたい場合は、-rオプションは不要であり、0開始アドレスをこの場合は変更できます)。1

sed同じアプローチのBSD版は次のようになります。

$ sed '1,/^[a-z]+=/{/^[a-z]+=/d
  }' testfile.txt

をエスケープする+必要があるのは、 がsed「最新の基本正規表現」ではなく「旧式の基本正規表現」を実装している場合のみです。私のシステム (Mac OS X) の BSDsedと GNU はどちらもsed「最新の」種類のようです。POSIX にはこの区別がなく、マニュアル (re_format(7)この区別を行っている BSD の場合) と POSIX 仕様を並べて読むと、頭が混乱してしまいます。

答え2

@John1024 申し訳ありませんが、あなたの解決策は、最初に一致する行がファイルの最初の行である場合にのみ機能します。

私は次のコードで問題を解決しましたsed -r '0,/^[a-z]\+=/{//d;}' testfile.txtが、以前の解決策は posix sed でも機能するはずだと確信しています。

実際のところ、2 行目のアドレスとして 0 行のオフセットを指定するというアイデアでしたが、それでも次の行も削除されてしまうので、バグのようです。

man sedUbuntu 14.04から

... addr1,+N は addr1 と addr1 に続く N 行に一致します。...

関連情報