特定の文字列を含むすべての行をテキストファイルから削除する方法


回答:


2759

行を削除して、出力を標準出力に出力するには、次のようにします。

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

13
ありがとう、しかしそれはファイルからそれを消去するようではなく、その文字列なしでテキストファイルの内容を印刷するだけです。
時計じかけのオレンジ

115
@A時計仕掛け:はい、出力を次のような新しいファイルにリダイレクトする必要があります。sed '/pattern to match/d' ./infile > ./newfileまたは、インプレース編集を行う場合は、のように-iフラグをsedに追加できますsed -i '/pattern to match/d' ./infile。この-iフラグはGNU sedを必要とし、移植性がないことに注意してください
SiegeX

16
sedのいくつかのフレーバーについて。sedの「-i」フラグを使用するには、拡張機能を提供する必要がありました。(例sed -i.backup '/pattern to match/d' ./infile)これにより、インプレース編集が可能になりました。
avelis 2013年

9
@SiegeXさらに良いsedことに、バージョン管理されていないファイルにコマンドを適用しないでください。
MatrixFrog 2013

84
Mac OS Xユーザーのためのもう1つの注意:何らかの理由で、-iフラグは、のように空の文字列であっても、引数を渡す必要がありますsed -i '' '/pattern/d' ./infile
geerlingguy 2013年

631

他にも特定の文字列を含む行を削除する方法は他にもたくさんあります sed

AWK

awk '!/pattern/' file > temp && mv temp file

Ruby(1.9以降)

ruby -i.bak -ne 'print if not /test/' file

Perl

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

4
パターンを持つ特定の行とそのすぐ上の行を削除する方法は?私は、異なるデータの間に数千のそのような行がある罰金を持っています。
oortcloud_domicile 2013

1
OS / Xでは、シェルバリエーションは先行スペースを保持しませんが、grep -vバリエーションは私にとってうまくいきました。
Paul Beusterien、2014

13
このsed例では動作が異なります。それはのようなものでなければなりません sed -n -i '/pattern/!p' file
シーザーソル2014年

8
すべての行がパターンに一致する場合、grepバージョンは機能しません。より良い方法:grep -v "pattern" file > temp; mv temp fileこれは、戻り値によっては、他のいくつかの例に適用される場合があります。
Chris Maes

1
「逆の印刷は実際の削除よりも速い」-私のマシンではありません(2012 MacBook Air、OS X 10.13.2)。ファイルを作成:seq -f %f 10000000 >foo.txt。sed d:time sed -i '' '/6543210/d' foo.txt実際の0m9.294s。sed!p:time sed -i '' -n '/6543210/!p' foo.txt実数0m13.671s。(ファイルが小さいほど、その差は大きくなります。)
jcsahnwaldtは、GoFundMonicaを2018年

252

sedを使用して、ファイル内の所定の行を置き換えることができます。ただし、grepを使用して2番目のファイルにインバースし、2番目のファイルを元のファイルに移動するよりもはるかに遅いようです。

例えば

sed -i '/pattern/d' filename      

または

grep -v "pattern" filename > filename2; mv filename2 filename

とにかく、最初のコマンドは私のマシンで3倍長くかかります。


19
パフォーマンス比較を試みたからといって、答えも投票してください!
anuragw

4
+1は、現在のファイルをgrep行で上書きするオプションを提供します。
Rhyuk 2013年

2
2番目の「grep」ソリューションも大きなファイルに適しています
simoes

3
パフォーマンスの違いが何であるか知りたいのですがsed '/pattern/d' filename > filename2; mv filename2 filename
ピート14

9
(ubuntuの/ usr / share / dict / wordsを使用)grepおよびmv:0.010s | 所定の位置にsed:0.197秒| sedおよびmv:0.031s
ReactiveRaven、

77

GNUでそれを行う簡単な方法sed

sed --in-place '/some string here/d' yourfile

56
このQ&Aスレッドに出くわし、シェルスクリプトを初めて使用する他のユーザーのための便利なヒント:コマンドラインで一度だけ使用する場合は短いオプションで問題ありませんが、読みやすいため、スクリプトでは長いオプションをお勧めします。
Dennis

3
--in-placeフラグの場合は+1。権限で保護されたファイルでテストする必要があります。(ユーザーによるスクラブが必要です。)
Bee Kay

8
longオプションはGNU sedでのみ使用できることに注意してください。MacおよびBSDユーザーは、この方法でgsedをインストールする必要があります。
マット

別のヒント:正規表現が一致しない場合は、-rオプションを試してください(または-E、バージョンによっては)。これは、正規表現のメタ文字の使用を可能にし+?{...}(...)
rjh

これは、ディスクに空き容量がなく、テキストを別のファイルにコピーできない場合の正解です。このコマンドは質問されたことを実行しますか?
ferreirabraga

38

ex(標準のUnixコマンドベースのエディターである)の使用を検討してください。

ex +g/match/d -cwq file

どこ:

  • +指定されたExコマンド(man ex-cを実行します。実行wq(書き込みと終了)と同じです。
  • g/match/d-指定されたmatchで行を削除するexコマンド、参照:Power of g

上記の例は、Unix.SEおよびのPOSIX仕様のexこの投稿に従ってファイルをインプレース編集するためのPOSIX準拠の方法です


との違いsedは次のとおりです。

sedあるS tream ED itor、ないファイルエディタが。BashFAQ

移植性のないコード、I / Oオーバーヘッド、およびその他のいくつかの悪い副作用を楽しんでいない限り。そのため、基本的に一部のパラメーター(in-place /など-i)は非標準のFreeBSD拡張であり、他のオペレーティングシステムでは使用できない場合があります。


5
それは素晴らしい...私がman exそれをするときに私に男を与えるときvim、それexはvimの一部のようです...もし私が正しく理解すれば、パターン構文matchvimregex.comであることを意味します。
エントロピー2015年

1
:g あるPOSIX準拠の一部を使用して、コマンドのわずかな違い。PCREはそれに基づいていると思います。
kenorb 2016年

16

私はMacでこれに苦労していました。さらに、変数置換を使用してそれを行う必要がありました。

だから私は使用しました:

sed -i '' "/$pattern/d" $file

どこ$fileで削除が必要なファイルであり、$pattern削除のために一致するパターンですが。

私は''このコメントから選びました

ここで注意すべき事はの使用である二重引用符の中で"/$pattern/d"。単一引用符を使用すると、変数は機能しません。


3
Macはsed後にパラメータを必要とし-i、バックアップをしたくないのであれば、あなたはまだ空の文字列を追加する必要があります:-i ''
wisbucky

シェル用sed -i "/$pattern/d" $file。お返事ありがとうございます。
アシュワカル

14

約345 000行を含むファイルで小さなベンチマークを作成しました。との道はgrep約15倍速いようですsed方法は、この場合の方法ようです。

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

どのプラットフォームを使用していますか?sed / perl / grepのどのバージョンを使用していますか?
hagello 2018

私が使用しているプラ​​ットフォームはLinux(Gentoo)です。sedバージョンはGNU sed v 4.2.2、perlバージョンperl 5(テスト時にどのリビジョンを使用したかわかりません)、grep(GNU)はバージョン3.0です。
ジャジア

14

これを使用することもできます:

 grep -v 'pattern' filename

ここで-vは、パターン(つまり、反転一致)以外のみが印刷されます。


特定の文字列を含むディレクトリの行を削除するにはどうすればよいですか
namannimmo

13

あなたがインプレースのような結果をgrep得るには、これを行うことができます:

echo "$(grep -v "pattern" filename)" >filename

4
これはbashシェルまたは同様のものにのみ有効です(ではありませんtcsh)。
2015年


4
perl -i    -nle'/regexp/||print' file1 file2 file3
perl -i.bk -nle'/regexp/||print' file1 file2 file3

最初のコマンドは、ファイルをインプレースで編集します(-i)。

2番目のコマンドは同じことを行いますが、ファイル名に.bkを追加することにより、元のファイルのコピーまたはバックアップを保持します(.bkは任意に変更できます)。



2

文字列の完全一致に対して誰かがそれを実行したい場合に備えて-w、grep-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複数の正確なパターンを一度に除外したい場合も、フラグと連携します。「ブラックリスト」が、「ファイル」から削除する各行にいくつかのパターンがあるファイルの場合:

grep -w -v -f blacklist file

少し誤解を招く。-w, --word-regexp Select only those lines containing matches that form whole words.-x, --line-regexp Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing the pattern and then surrounding it with ^ and $.
サイ


0

処理されたテキストをコンソールに表示するには

cat filename | sed '/text to remove/d' 

処理されたテキストをファイルに保存するには

cat filename | sed '/text to remove/d' > newfile

処理されたテキスト情報を既存のファイルに追加する

cat filename | sed '/text to remove/d' >> newfile

既に処理されたテキストを処理するには、この場合、削除されたものの行をさらに削除します

cat filename | sed '/text to remove/d' | sed '/remove this too/d' | more

| more一度に1ページのチャンク内のテキストが表示されます。


0

古き良きものedを使用してを使用する回答と同様の方法でファイルを編集できますex。この場合の大きな違いedは、コマンドライン引数としてではなく、標準入力を介してコマンドを受け取るexことです。スクリプトで使用する場合、これに対応する通常の方法は、printfコマンドをパイプするために使用することです。

printf "%s\n" "g/pattern/d" w | ed -s filename

またはヒアドキュメント付き:

ed -s filename <<EOF
g/pattern/d
w
EOF
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.