如何只获得唯一的结果而不必对数据进行排序?

Laz*_*zer 55 text-processing uniq

$ cat data.txt 
aaaaaa
aaaaaa
cccccc
aaaaaa
aaaaaa
bbbbbb
$ cat data.txt | uniq
aaaaaa
cccccc
aaaaaa
bbbbbb
$ cat data.txt | sort | uniq
aaaaaa
bbbbbb
cccccc
$
Run Code Online (Sandbox Code Playgroud)

我需要的结果是显示原始文件中的所有行,删除所有重复项(不仅仅是连续的),同时保持文件中语句的原始顺序

在这里,在这个例子中,我实际上正在寻找的结果是

aaaaaa
cccccc
bbbbbb
Run Code Online (Sandbox Code Playgroud)

uniq一般如何执行此通用操作?

cjm*_*cjm 66

perl -ne 'print unless $seen{$_}++' data.txt
Run Code Online (Sandbox Code Playgroud)

或者,如果您必须无用地使用cat

cat data.txt | perl -ne 'print unless $seen{$_}++'
Run Code Online (Sandbox Code Playgroud)

这是awk针对缺少 Perl 的系统的翻译:

awk '!seen[$0]++' data.txt
cat data.txt | awk '!seen[$0]++'
Run Code Online (Sandbox Code Playgroud)

  • 通过省略`if`、`print`、括号和大括号,awk 版本可以变得更短:`awk '!seen[$0]++'` (12认同)
  • 一个稍短的 awk 脚本是 `{ if (!seen[$0]++) print }` (4认同)
  • @Legate,这是[数组](http://www.gnu.org/software/gawk/manual/gawk.html#Arrays) 的名称,我们在其中记录了我们看到的每一行。对于所有 awk 问题,您可以将其更改为 `'!LarryWall[$0]++'`,但是“seen”可以帮助人们更好地理解程序。 (2认同)

bin*_*lse 15

约翰有一个工具叫unique

usr@srv % cat data.txt | unique out
usr@srv % cat out
aaaaaa
cccccc
bbbbbb
Run Code Online (Sandbox Code Playgroud)

要在单个命令行中不使用其他工具来实现相同的功能有点复杂:

usr@srv % cat data.txt | nl | sort -k 2 | uniq -f 1 | sort -n | sed 's/\s*[0-9]\+\s\+//'
aaaaaa
cccccc
bbbbbb
Run Code Online (Sandbox Code Playgroud)

nl在行前打印行号,所以如果我们sort/uniq在他们后面,我们可以恢复行的原始顺序。sed之后只删除行号;)


men*_*kus 7

我更喜欢使用这个:

cat -n data.txt | sort --key=2.1 -b -u | sort -n | cut -c8-
Run Code Online (Sandbox Code Playgroud)

cat -n 添加行号,

sort --key=2.1 -b -u 在第二个字段上排序(在添加的行号之后),忽略前导空格,保留唯一行

sort -n 按严格的数字顺序排序

cut -c8- 保留第 8 列到 EOL 的所有字符(即,省略我们包含的行号)

  • “无需对数据进行排序”仅出现在标题中。实际需要是:“显示原始文件中的所有行,删除所有重复项(不仅仅是连续的),同时保持文件中语句的原始顺序。” (7认同)
  • >如何只得到唯一的结果而不需要对数据进行排序?> 无需对数据进行排序 (6认同)