ターゲット
この行を含め、テキストファイルから一致する行の前のすべての行をどのように削除しますか?
入力ファイルの例:
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
代わりに。1
POSIX 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を使用してそれまでパイプして削除します。