shell - sed取出特定行




刪除包含特定字符串的文本文件中的行 (9)

SED:

AWK:

GREP:

我將如何使用sed刪除包含特定字符串的文本文件中的所有行?


echo -e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt


你可以考慮使用ex (這是一個標準的基於UNIX命令的編輯器):

ex +g/match/d -cwq file

哪裡:

  • +執行給定的Ex命令( man ex ),與執行wq (寫入和退出)的-c相同,
  • g/match/d - 用於刪除給定match行的Ex命令,請參閱: g的功率

上面的例子是符合POSIX標準的方法,用於在Unix.SEPOSIX規範中就地編輯文件。

sed的區別在於:

sed是一個文件編輯器,而不是文件編輯器。 BashFAQ

除非你喜歡不可移植的代碼,I / O開銷和一些其他不良的副作用。 所以基本上一些參數(如in-place / -i )是非標準的FreeBSD擴展,可能在其他操作系統上不可用。


使用GNU sed的簡單方法:

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

我在Mac上苦苦掙扎。 另外,我需要使用變量替換。 所以我用:

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

其中$file是需要刪除的文件, $pattern是要刪除的模式。 從這個comment選擇了'' 。 這裡要注意的是在"/$pattern/d"使用雙引號 。 當我們使用單引號時,變量不起作用。


我用一個包含大約345000行的文件做了一個小基準。 在這種情況下,使用grep的方式似乎比sed方法快15倍。

我曾嘗試使用LC_ALL = C和沒有使用LC_ALL,但它並沒有顯著改變計時。 搜索字符串(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中使用-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標誌。 如果“黑名單”是每行中要從“文件”中刪除的具有多種模式的文件:

grep -w -v -f blacklist file

要刪除該行並將輸出打印到標準輸出:

sed '/pattern to match/d' ./infile

要直接修改文件:

sed -i '/pattern to match/d' ./infile

直接修改文件(並創建備份):

sed -i.bak '/pattern to match/d' ./infile

對於Mac OS X用戶:

sed -i '' '/pattern/d' ./infile

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

第一條命令在位置(-i)編輯文件。

第二個命令執行相同的操作,但通過向文件名添加.bk保存原始文件的副本或備份(.bk可以更改為任何內容)。





in-place