在保持顺序的同时删除相邻的重复行


11

我有一个带有一列的文件,每个文件的名称重复多次。我想将每个重复压缩为一个,同时保留与相同名称的其他重复不相邻的任何相同名称的重复。

例如,我想将左侧转向右侧:

Golgb1    Golgb1    
Golgb1    Akna
Golgb1    Spata20
Golgb1    Golgb1
Golgb1    Akna
Akna
Akna
Akna
Spata20
Spata20
Spata20
Golgb1
Golgb1
Golgb1
Akna
Akna
Akna

这就是我一直在使用的perl -ne 'print if ++$k{$_}==1' file.txt > file2.txt 方法:但是,此方法仅使左边代表一个(即,Golb1和Akna不再重复)。

有没有一种方法可以为每个块保留唯一的名称,同时保留在多个不相邻的块中重复的名称?

Answers:


23

uniq 将为您做到这一点:

$ uniq inputfile
Golgb1
Akna
Spata20
Golgb1
Akna

2
哇,真是尴尬!谢谢!
Age87 '18

@ Age87 Unix很棒!这仅能起作用,因为您希望重复项已经相邻(或者,不希望删除不相邻的重复项)。通常,建议使用sort | uniq
jpaugh

1
或更简洁地说,sort -u(:
DopeGhoti '18


6

试试这个-保存上一行并与当前行进行比较

$ perl -ne 'print if $p ne $_; $p=$_' ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

您也已标记uniq-尝试过吗?

$ uniq ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

1

使用sed可以完成以下操作:

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

这里我们在模式空间中随时有2行。当它们之间的比较失败时,我们将第一个打印出来并从前面切下然后返回,然后将下一行追加到模式空间中。冲洗...重复

在Slurp模式下使用Perl,我们将整个文件视为一个长字符串,在该字符串上应用了regex,它会为您进行比较。

perl -0777pe 's//$1/ while /^(.*\n)\1+/gm' input_file

0

有关Rakesh Sharma的sed解决方案的问题。

如果您有一个输入文件,例如:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.118 48.216
-126.128 48.222
-126.136 48.226

您希望输出文件为:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.128 48.222
-126.136 48.226

请注意缺少的内容:

-126.118 48.216

我知道我想要的命令类似于您的解决方案:

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

无法以正确的方式更改它以打印两个列,并且只能以这种特殊的方式对第2列的值进行排序。有小费吗?


sed -e '$!N' -e '/.*\.\([0-9]*\)\n.*\.\1$/!{P;D;}' -e 's/\n.*//;s/^/\n/;D' 将删除后续的重复元素。注意:这需要GNU sed。对于POSIX行为,需要稍作改动。
Rakesh Sharma
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.