2016-06-11 44 views
2

我試圖從文件中刪除重複的行並更新文件。出於某種原因,我必須將其寫入新文件並將其替換。這是唯一的方法嗎?刪除重複行並覆蓋相同命令中的文件

awk '!seen[$0]++' .gitignore > .gitignore 

awk '!seen[$0]++' .gitignore > .gitignore_new && mv .gitignore_new .gitignore 
+0

文件輸出這是隻有**聰明**的方式。可以在原位刪除,但需要打開文件而不會截斷。然後當它被寫入時,它必須被截斷爲新的大小。即使我們不考慮操作被中斷時的情況,也留下一個半熟的文件是一件麻煩事。 – Kaz

回答

-1

是的,因爲如果你不這樣做,外殼將創建文件描述符並截斷AWK過程開始之前就的.gitignore。

6

重定向到相同的輸出文件作爲像輸入文件:

awk '!seen[$0]++' .gitignore > .gitignore 

將與一個空文件結束。這是因爲使用>運算符,外殼將在命令get執行之前打開並截斷文件。含義你將失去​​你所有的數據。

隨着GNU的較新版本的awk可以使用-i inplace選項編輯文件到位

awk -i inplace '!seen[$0]++' .gitignore 

如果沒有最近的GNU版本的awk,你需要來創建臨時文件:

awk '!seen[$0]++' .gitignore > .gitignore.tmp 
mv .gitignore.tmp .gitignore 

另一種選擇是從moreutils使用sponge程序:

awk '!seen[$0]++' .gitignore | sponge .gitignore 

sponge將浸泡所有stdinput並在此之後打開輸出文件。在寫入之前,這可以有效地保持輸入文件的完整性。

+1

不起作用。 'gawk:fatal:無法打開源文件\'!閱讀[$ 0] ++'(無此文件或目錄)''。 – Kaz

+0

Robbins於2016年6月6日提交'4f758771937fcbd59b1fd2db017c4995513c3988',在'master'分支上使用'gawk'。 – Kaz

+0

@Kaz正如我所說的,'-i'是一個相對較新的gawk功能。看起來你的'gawk'不支持它。 – hek2mgl

1

托馬斯,我認爲問題在於你正在閱讀它並在同一命令上寫入它。這就是爲什麼你必須首先把臨時文件。

的>不覆蓋,讓你使用了正確的重定向操作從命令

  • 將輸出重定向到磁盤上的文件。注意:如果文件已經存在,它將被刪除並在沒有警告的情況下被覆蓋,所以請注意。

例:PS -ax> processes.txt使用ps命令來獲取系統上運行 進程的列表,以及存儲在名爲 processes.txt