特定の文字列を含むテキストファイル内のすべての行を削除するのにsedをどのように使用しますか
行を削除して出力を標準出力に出力するには、次のようにします。
sed '/pattern to match/d' ./infile
ファイルを直接変更するには
sed -i '/pattern to match/d' ./infile
ファイルを直接変更する(そしてバックアップを作成する)には:
sed -i.bak '/pattern to match/d' ./infile
Mac OS XおよびFreeBSDユーザーの場合:
sed -i '' '/pattern/d' ./infile
sed
以外にも、特定の文字列を含む行を削除する方法は他にもたくさんあります。
awk '!/pattern/' file > temp && mv temp file
Ruby -i.bak -ne 'print if not /test/' file
Perl -ni.bak -e "print unless /pattern/" file
while read -r line
do
[[ ! $line =~ pattern ]] && echo "$line"
done <file > o
mv o file
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倍長くかかります。
簡単な方法は、GNU sed
:
sed --in-place '/some string here/d' yourfile
あなたは ex
(これは標準のUnixコマンドベースのエディタです)を使うことを考えるかもしれません:
ex +g/match/d -cwq file
ここで、
wq
を実行する+
と同じように、man ex
は与えられたExコマンド(-c
)を実行します(writeとquit)。g/match/d
- 与えられたmatch
を持つ行を削除するExコマンド。参照: gの累乗上記の例は、この Unix.SEに投稿 および ex
のように、ファイルをインプレース編集するためのPOSIX準拠の方法です。
sed
との違いは、
sed
は _ s _ tream _ ed _ itorであり、ファイルエディタではありません。BashFAQ
移植できないコード、I/Oオーバーヘッド、その他の悪い副作用を楽しんでいない限り。そのため、基本的には(in-place/-i
のような)いくつかのパラメータは標準ではないFreeBSDの拡張機能であり、他のオペレーティングシステムでは利用できないかもしれません。
私はMac上でこれに苦労していました。さらに、変数置換を使用してそれを実行する必要がありました。
だから私は使用しました:
sed -i '' "/$pattern/d" $file
$file
は削除が必要なファイルで、$pattern
は削除のために照合されるパターンです。
私はこの コメント から''
を選びました。
ここで注意すべきことは"/$pattern/d"
で 二重引用符 を使用することです。一重引用符を使用すると、変数は機能しません。
grep
でインプレース風の結果を得るためには、これを実行できます。
echo "$(grep -v "pattern" filename)" >filename
私は約34万5000行を含むファイルで小さなベンチマークを作成しました。この場合のgrep
メソッドはsed
メソッドよりも約15倍速いようです。
LC_ALL = Cを設定してもしなくても試してみましたが、タイミングが大きく変わることはありません。検索文字列(CDGA_00004.pdbqt.gz.tar)はファイルの途中のどこかにあります。
コマンドとタイミングは次のとおりです。
time sed -i "/CDGA_00004.pdbqt.gz.tar/d" /tmp/input.txt
real 0m0.711s
user 0m0.179s
sys 0m0.530s
time Perl -ni -e 'print unless /CDGA_00004.pdbqt.gz.tar/' /tmp/input.txt
real 0m0.105s
user 0m0.088s
sys 0m0.016s
time (grep -v CDGA_00004.pdbqt.gz.tar /tmp/input.txt > /tmp/input.tmp; mv /tmp/input.tmp /tmp/input.txt )
real 0m0.046s
user 0m0.014s
sys 0m0.019s
これを使うこともできます。
grep -v 'pattern' filename
ここで-v
はあなたのパターン以外のものだけを印刷するでしょう(それは逆マッチを意味します)。
echo -e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt
Perl -i -nle'/regexp/||print' file1 file2 file3
Perl -i.bk -nle'/regexp/||print' file1 file2 file3
最初のコマンドは、ファイルをその場で編集します(-i)。
2番目のコマンドも同じことを行いますが、ファイル名に.bkを追加することで元のファイルのコピーまたはバックアップを保持します(.bkは任意の名前に変更できます)。
cat filename | grep -v "pattern" > filename.1
mv filename.1 filename
万が一、文字列が完全に一致するようにしたい場合は、grep-wの-w
フラグを使用してください。たとえば、番号11の行を削除したいが、番号111の行を残したい場合は、次のようになります。
-bash-4.1$ head file
1
11
111
-bash-4.1$ grep -v "11" file
1
-bash-4.1$ grep -w -v "11" file
1
111
同時に複数の正確なパターンを除外したい場合は、-f
フラグと一緒に機能します。 "blacklist"が "file"から削除したい各行に複数のパターンを持つファイルであるならば:
grep -w -v -f blacklist file