sed を使用して、特定の文字列を含むテキスト ファイル内のすべての行を削除するにはどうすればよいですか?
20 に答える
行を削除して出力を標準出力に出力するには:
sed '/pattern to match/d' ./infile
ファイルを直接変更するには – BSD sed では機能しません:
sed -i '/pattern to match/d' ./infile
同じですが、BSD sed (Mac OS X および FreeBSD) の場合 – GNU sed では動作しません:
sed -i '' '/pattern to match/d' ./infile
ファイルを直接変更 (およびバックアップを作成) するには、BSD および GNU sed で動作します。
sed -i.bak '/pattern to match/d' ./infile
特定の文字列を含む行を削除するには、他にも多くの方法がありますsed
。
AWK
awk '!/pattern/' file > temp && mv temp file
ルビー (1.9+)
ruby -i.bak -ne 'print if not /test/' file
パール
perl -ni.bak -e "print unless /pattern/" file
シェル (bash 3.2 以降)
while read -r line
do
[[ ! $line =~ pattern ]] && echo "$line"
done <file > o
mv o file
GNU grep
grep -v "pattern" file > temp && mv temp file
そしてもちろんsed
(逆の印刷は実際の削除よりも高速です):
sed -n '/pattern/!p' file
sed を使用して、ファイル内の行を置き換えることができます。ただし、逆にgrepを使用して2番目のファイルに移動し、2番目のファイルを元のファイルに移動するよりもはるかに遅いようです。
例えば
sed -i '/pattern/d' filename
また
grep -v "pattern" filename > filename2; mv filename2 filename
とにかく、私のマシンでは最初のコマンドに3倍の時間がかかります。
以下の使用を検討してくださいex
(標準の Unix コマンドベースのエディターです)。
ex +g/match/d -cwq file
どこ:
+
指定された Ex コマンド ( ) を実行します。 (書き込みと終了)を実行するman ex
のと同じです。-c
wq
g/match/d
- 指定された で行を削除する Ex コマンドmatch
、参照: Power of g
上記の例は、Unix.SE のこの投稿および のPOSIX 仕様に従って、ファイルをインプレース編集するための POSIX 準拠の方法ですex
。
との違いsed
は次のとおりです。
sed
は、ファイルエディタではなく、ストリーム エディタです。Bashよくある質問
移植性のないコード、I/O オーバーヘッド、およびその他の悪い副作用を楽しんでいる場合を除きます。したがって、基本的に一部のパラメーター ( in-place/ など-i
) は非標準の FreeBSD 拡張機能であり、他のオペレーティング システムでは使用できない場合があります。
インプレースのような結果を得るには、次のようにしgrep
ます。
echo "$(grep -v "pattern" filename)" >filename
perl -i -nle'/regexp/||print' file1 file2 file3
perl -i.bk -nle'/regexp/||print' file1 file2 file3
最初のコマンドは、ファイルをその場で編集します (-i)。
2 番目のコマンドは同じことを行いますが、ファイル名に .bk を追加することで元のファイルのコピーまたはバックアップを保持します (.bk は任意の名前に変更できます)。
echo -e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt
興味深いことに、受け入れられた回答は、実際には質問に直接回答していません。質問は sed を使用して文字列を置き換えることについて尋ねますが、答えは任意の文字列を正規表現に変換する方法の知識を前提としているようです。
多くのプログラミング言語ライブラリには、このような変換を実行する関数があります。
python: re.escape(STRING)
ruby: Regexp.escape(STRING)
java: Pattern.quote(STRING)
しかし、コマンドラインでそれを行う方法は?
これは sed 指向の質問であるため、1 つのアプローチは sed 自体を使用することです。
sed 's/\([\[/({.*+^$?]\)/\\\1/g'
したがって、任意の文字列 $STRING を指定すると、次のように記述できます。
re=$(sed 's/\([\[({.*+^$?]\)/\\\1/g' <<< "$STRING")
sed "/$re/d" FILE
またはワンライナーとして:
sed "/$(sed 's/\([\[/({.*+^$?]\)/\\\1/g' <<< "$STRING")/d"
このページの他の場所で説明されているように、バリエーションがあります。