sed:この行を含む、一致する行の前のすべての行を削除します。

sed:この行を含む、一致する行の前のすべての行を削除します。

ターゲット

この行を含め、テキストファイルから一致する行の前のすべての行をどのように削除しますか?

入力ファイルの例:

apple
pear
banana
HI_THERE
lemon
coconut
orange

希望の出力:

lemon
coconut
orange

目的は、sed(直接編集)で「-i」オプションを使用することです。

クリーンなソリューション?

同様の質問に対するほとんどの回答は、同様の内容を示唆しています。

sed -n '/HI_THERE/,$p' input_file

ただし、一致する行は削除されません。

HI_THERE
lemon
coconut
orange

これがわかると、一致する行(含む)からファイルの終わりまですべての内容が削除されます。

sed '/HI_THERE/,$d' input_file

私は次のことを試しました:

sed '^,/HI_THERE/d' input_file

しかし、sedは次のように文句を言いました。

sed: -e expression #1, char 1: unknown command: `^'

汚い解決策

最後の(汚れた)解決策はパイプを使用することです。

sed -n '/HI_THERE/,$p' input_file | tail -n +2

ただし、ファイルを直接編集することは機能しません。

sed -n '/HI_THERE/,$p' input_file | tail -n +2 > input_file
cat input_file # returns nothing

このような一時ファイルを使用する必要があります...

sed -n '/HI_THERE/,$p' input_file | tail -n +2 > tmp_file
mv tmp_file input_file

答え1

「クリーンなソリューション」に似ています。

sed -e '1,/HI_THERE/d' input_file

ファイルの最初の行は1行です。^常に知っているので特別なアドレスがなく、$どの行なのか分からないので、最後にあるwhileが必要です。

一致する行がある場合最初ファイルの行。 GNU sedを使用すると、0代わりに。1POSIX sedと移植性(この場合は別のように見えます)の場合、より複雑です(以下の説明とこのフォローアップの質問)。

答え2

Posix sed を引き続き使用するには、次のものを使用できます。

sed -ne '
  /HI_THERE/!d
  :loop
    n
    p
  bloop
' inp.file

または、より簡潔に書くと、次のようになります。

sed -n '/HI_THERE/!d;:a;n;p;ba' inp.file

答え3

$ perl -ne 'print if 1 <(/HI_THERE/...eof)' input_file

範囲演算子を使用して...適切な範囲を形成し、選択した範囲内の最初の要素を拒否するようにさらに制限します。

答え4

grep -nw HI_THERE file.txt |awk -F":" '{print $1}' | xargs -I % sed '1,%d' file.txt

w説明:行番号を取得するために正確な単語grepを使用してください。n
次に、awkを使用して行番号を抽出し、区切り文字は次のようになります。:
その後、xargsを使用してそれまでパイプして削除します。

関連情報