2016-06-11 46 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