如何删除文件中的重复行?
How to remove duplicate lines in a file?
我知道一般的方法是使用类似
的东西
$ sort file1.txt | uniq > file2.txt
但我想知道是否有一种方法可以在不需要单独的源文件和目标文件的情况下执行此操作,即使这意味着它不能是单行文件。
一个常见的成语是:
temp=$(mktemp)
some_pipeline < original.file > "$temp" && mv "$temp" original.file
&&
很重要:如果管道失败,则原始文件不会被(可能)垃圾覆盖。
Linux moreutils
包中包含一个封装此程序的程序:
some_pipeline < original.file | sponge original.file
使用 GNU awk 进行“就地”编辑:
awk -i inplace '!seen[[=10=]]++' file1.txt
与所有支持“就地”编辑的工具(ed
除外,它需要先将整个文件读入内存)(sed -i
、perl -i
、ruby -i
, 等等) 这在幕后使用了一个临时文件。
使用任何 awk,您都可以在不使用临时文件的情况下执行以下操作,而是使用大约两倍的内存:
awk '!seen[[=11=]]++{a[++n]=[=11=]} END{for (i=1;i<=n;i++) print a[i] > FILENAME}' file
使用 Perl 的 -i
:
perl -i -lne 'print unless $seen{$_}++' original.file
-i
“就地”更改文件;
-n
逐行读取输入,运行每行代码;
-l
从输入中删除换行符并将它们添加到 print
;
%seen
哈希惯用语在 perlfaq4 中有描述。
只需使用 sort
的 -o
和 -u
选项:
sort -o file -u file
您甚至不需要为其他命令使用管道,例如 uniq
。
使用sed
$ sed -i -n 'G;/^\(.*\n\).*\n$/d;H;P' input_file
G
- 追加保留 space.
/^\(.*\n\).*\n$/d
- 使用back-referencing,匹配并删除重复的行。
H
- 复制模式 space 以保留 space.
P
- 打印当前模式 space 到第一个换行符。
我知道一般的方法是使用类似
的东西$ sort file1.txt | uniq > file2.txt
但我想知道是否有一种方法可以在不需要单独的源文件和目标文件的情况下执行此操作,即使这意味着它不能是单行文件。
一个常见的成语是:
temp=$(mktemp)
some_pipeline < original.file > "$temp" && mv "$temp" original.file
&&
很重要:如果管道失败,则原始文件不会被(可能)垃圾覆盖。
Linux moreutils
包中包含一个封装此程序的程序:
some_pipeline < original.file | sponge original.file
使用 GNU awk 进行“就地”编辑:
awk -i inplace '!seen[[=10=]]++' file1.txt
与所有支持“就地”编辑的工具(ed
除外,它需要先将整个文件读入内存)(sed -i
、perl -i
、ruby -i
, 等等) 这在幕后使用了一个临时文件。
使用任何 awk,您都可以在不使用临时文件的情况下执行以下操作,而是使用大约两倍的内存:
awk '!seen[[=11=]]++{a[++n]=[=11=]} END{for (i=1;i<=n;i++) print a[i] > FILENAME}' file
使用 Perl 的 -i
:
perl -i -lne 'print unless $seen{$_}++' original.file
-i
“就地”更改文件;-n
逐行读取输入,运行每行代码;-l
从输入中删除换行符并将它们添加到print
;%seen
哈希惯用语在 perlfaq4 中有描述。
只需使用 sort
的 -o
和 -u
选项:
sort -o file -u file
您甚至不需要为其他命令使用管道,例如 uniq
。
使用sed
$ sed -i -n 'G;/^\(.*\n\).*\n$/d;H;P' input_file
G
- 追加保留 space./^\(.*\n\).*\n$/d
- 使用back-referencing,匹配并删除重复的行。H
- 复制模式 space 以保留 space.P
- 打印当前模式 space 到第一个换行符。