2013-07-05 35 views
4

我想遍歷文件並刪除某些行。示例文件:在文件中循環並刪除某些行

的test.txt

a 
b 
c 
d 

我有什麼:

FILE=/tmp/test.txt 
while read FILE 
do 
    # if the line starts with b delete it otherwise leave it there 
    ? 
done 
+0

'read'從標準輸入中讀取一行,而不是從文件中讀取您期望的代碼。你應該重定向'stdin'從文件中獲取一行,請參閱:Duffy的答案。但是這個任務'sed'或'grep'更快。 – jm666

+0

@ jm666較大文件較快,但不適用於較短文件。 'fork()'/'exec()'相比於只使用shell內建函數的東西是一個很大的開銷。 –

+0

@CharlesDuffy你是對的。在80線以下的筆記本中,bash速度更快。 80以上的sed速度更快,超過300行grep速度也更快。 :)取決於,你叫什麼「大文件」:) – jm666

回答

8

這是sed一份工作 - 在UNIX流編輯器:

(sed '/^b/d' yourfile > yourfile~ && mv yourfile~ yourfile) || rm yourfile~ 

的命令將刪除所有以開頭的行210並將剩餘行寫入備份文件。如果成功,備份文件將被重命名爲原始文件,如果失敗備份文件將被刪除。

+0

是啊實際上與sed更容易做到 – DRC

+0

@DRC只有當你使用非POSIX功能; sed的'-i'標誌是非標準的,並且在所有實現中可能不存在。如果你想要一個能夠進行就地操作的標準化編輯器,你可以使用'ex'或'ed',而不是'sed'。 –

+0

@CharlesDuffy如果你確實有一個不支持'-i'的版本,你可以使用:'sed'/^1/d'file2> file2_; mv file2_ file2' – hek2mgl

4

你可以用grep的oneliner做到這一點:

grep -v "^b" test.txt > newfile 
2

輕鬆使用bash完成內置功能:

while read -r; do 
    [[ $REPLY = b* ]] || printf '%s\n' "$REPLY" 
done <file >file.new 
mv file.new file 
0

「的Perl ......它可能是你$PATH」: - )

使用$SHELL的微小文字的任務(即shkshzshbashtcsh,csh)在BSD,OSX,Linux,AIX,Solaris上與各種「標準POSIX」相對於sed,grep和其他實用程序的BSD,Linux和GNU擴展,並注意考慮gawkawk和古代版本許多服務器系統上的工具......可能很難。

perl -i.orig -ne 'print unless /^b/' test.txt 

它工作嗎?

diff test.txt test.txt.orig 
相關問題