如何删除重复的线路中的Unix文件?如何删除重复的线路中的Unix文件?(How can I del

2019-05-04 03:11发布

有没有办法删除在Unix系统中的文件重复行?

我可以做到这一点sort -uuniq命令,但我想用sedawk 。 那可能吗?

Answer 1:

awk '!seen[$0]++' file.txt

seen是一个关联-数组awk将通过该文件的每一行。 如果行不是阵列中然后seen[$0]将评估为假。 该! 是逻辑NOT运算符和将反转假为真。 awk将打印在表达式的值为真行。 所述++增量seen ,使得seen[$0] == 1在第一时间之后的线被发现,然后seen[$0] == 2 ,依此类推。
AWK评估一切,但0"" (空字符串)为true。 如果重复线路被放置在seen那么!seen[$0]会评估为false,该线路将不会被写入到输出。



Answer 2:

从http://sed.sourceforge.net/sed1line.txt :(请不要问我这是如何工作;-))

 # delete duplicate, consecutive lines from a file (emulates "uniq").
 # First line in a set of duplicate lines is kept, rest are deleted.
 sed '$!N; /^\(.*\)\n\1$/!P; D'

 # delete duplicate, nonconsecutive lines from a file. Beware not to
 # overflow the buffer size of the hold space, or else use GNU sed.
 sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'


Answer 3:

Perl的一个班轮类似@乔纳斯的awk的解决方案:

perl -ne 'print if ! $x{$_}++' file

这种变化比较删除之前结尾的空白:

perl -lne 's/\s*$//; print if ! $x{$_}++' file

这种变化编辑就地文件:

perl -i -ne 'print if ! $x{$_}++' file

这种变化快速修改的地方文件,使得备份file.bak

perl -i.bak -ne 'print if ! $x{$_}++' file


Answer 4:

一内衬安德烈 - 米勒上面贴的作品,除了最新版本的sed的时候输入文件以一个空行,并没有字符结束。 我的Mac上我的CPU只是旋转。

无限循环,如果最后一行是空的,没有字符

sed '$!N; /^\(.*\)\n\1$/!P; D'

不挂,但你失去了最后一行

sed '$d;N; /^\(.*\)\n\1$/!P; D'

【解说】在的最后sed的常见问题 :

GNU的sed的维护者认为,尽管便携性问题
这会导致,改变所述N个打印命令(而不是
删除)模式空间是与一个人的直觉更加一致
有关如何命令为“追加下一行” 应该的行为。
另一个事实有利于改变是“{N;指令;}”,将
删除最后一行,如果该文件是奇数行,但
打印的最后一行,如果文件中有偶数行的。

要转换其使用N的前行为脚本(删除
在达到EOF)与兼容脚本模式空间
sed的所有版本, 改变一个孤独的“N”; 到“$ d; N;”



Answer 5:

使用议会(Vi兼容)的另一种方法

删除重复的,连续的行从文件中:

vim -esu NONE +'g/\v^(.*)\n\1$/d' +wq

删除文件重复,不连续和非空行:

vim -esu NONE +'g/\v^(.+)$\_.{-}^\1$/d' +wq



Answer 6:

第一种解决方案也由http://sed.sourceforge.net/sed1line.txt

$ echo -e '1\n2\n2\n3\n3\n3\n4\n4\n4\n4\n5' |sed -nr '$!N;/^(.*)\n\1$/!P;D'
1
2
3
4
5

其核心思想是:

print ONLY once of each duplicate consecutive lines at its LAST appearance and use D command to implement LOOP.

解释:

  1. $!N; :如果当前行是不是最后一行,则使用N命令读取下一行到pattern space
  2. /^(.*)\n\1$/!P :如果当前的内容pattern space是2个duplicate string通过分隔\n ,这意味着下一行是same与电流线,我们不能根据打印我们的核心理念; 否则,这意味着当前行是其所有的重复连续的行的最后的外观,我们现在可以使用P命令打印字符在当前pattern space的util \n\n也打印)。
  3. D :我们使用D命令删除字符在当前pattern space的util \n\n也被删除),则内容pattern space是下一行。
  4. D命令将强制sed跳转到其FIRST命令$!N而不是从文件中读取或标准输入流的下一行。

第二种解决方案是容易(从自己)理解:

$ echo -e '1\n2\n2\n3\n3\n3\n4\n4\n4\n4\n5' |sed -nr 'p;:loop;$!N;s/^(.*)\n\1$/\1/;tloop;D'
1
2
3
4
5

其核心思想是:

print ONLY once of each duplicate consecutive lines at its FIRST appearance and use : command & t command to implement LOOP.

解释:

  1. 读取输入流或文件的新线,一旦打印。
  2. 使用:loop命令设置label命名loop
  3. 使用N到下一行读入pattern space
  4. 使用s/^(.*)\n\1$/\1/删除当前行,如果下一行是同当前行,我们使用s命令执行delete操作。
  5. 如果s成功执行的命令,然后使用tloop命令力sed跳转到label命名的loop ,这将做同样的循环到下一行UTIL有这行没有重复的连续行latest printed ; 否则,使用D命令来delete其是与同一行latest-printed line ,并迫使sed跳到第一命令,其是p命令,当前的内容pattern space是下一个新行。


Answer 7:

这可以用awk实现
下面这一行会显示独特价值

awk file_name | uniq

您可以输出这些独特的值到一个新文件

awk file_name | uniq > uniq_file_name

新的文件将uniq_file_name只包含唯一值,没有重复



Answer 8:

cat filename | sort | uniq -c | awk -F" " '$1<2 {print $2}'

删除使用awk中的重复行。



文章来源: How can I delete duplicate lines in a file in Unix?