删除文件每一行中的重复项

Ara*_*ash 7 linux bash perl uniq

如何删除每一行中的重复项,例如这里?

1 1 1 2 1 2 3
5 5 4 1 2 3 3
Run Code Online (Sandbox Code Playgroud)

我想得到这个输出:

1 2 3 
5 4 1 2 3
Run Code Online (Sandbox Code Playgroud)

有很多行(100,000),在每一行中我都想要唯一的值。Perl 可能是最快的,但我怎样才能在 Perl 或 Bash 中做到呢?

ner*_*ler 13

这是一个使用 awk 的选项:

awk '{ while(++i<=NF) printf (!a[$i]++) ? $i FS : ""; i=split("",a); print ""}' infile > outfile
Run Code Online (Sandbox Code Playgroud)

编辑更新评论:

  1. while (++i<=NF)

    初始化 while 循环,预加“i”,因为 $0 是 awk 中的完整行。

    所以它从 1 美元(第一个字段)开始。循环遍历该行直到结束(小于或等于 'NF',它内置于 awk 中,表示“字段数”)。默认字段分隔符是一个空格,您可以轻松更改默认分隔符。

  2. printf (!a[$i]++) ? $i FS : ""

    这是一个三元运算

    因此,如果 input 不在数组中!a[$i]++,则打印 $i,如果是,则打印 ""。(如果您不喜欢这种方式,可以删除!并反转$i FS : "")。

  3. i=split("",a)

    通常,这是一个空分割。在这种情况下,它为下一行重置 I。

  4. print ""

    结束输出行(实际上不是 100% 为什么),否则您将得到以下输出:

    1 2 3 5 4 1 2 3 代替
    1 2 3
    5 4 1 2 3

  • 为了帮助当前和未来的读者,请尝试在一定程度上记录答案。这是紧凑而高效的,但对于不太习惯 `awk` 的人来说,这是非常不可读的,因为它依赖于测试和操作顺序、三元运算符、`split("",a)` 怪癖来重置数组(和它用于重置`i`) 和特殊变量`NF` 和`FS` 的返回值。这样的解释使答案更好! (5认同)

slh*_*hck 5

因为ruby我知道的任何 Linux 发行版都有:

ruby -e 'STDIN.readlines.each { |l| l.split(" ").uniq.each { |e| print "#{e} " }; print "\n" }' < test
Run Code Online (Sandbox Code Playgroud)

这里,test是包含元素的文件。

为了解释这个命令的作用——尽管 Ruby 几乎可以从左到右阅读:

  • 读取输入(来自< test你的 shell)
  • 遍历输入的每一行
  • 根据分隔项目的一个空格将行拆分为一个数组 ( split(" "))
  • 从此数组中获取唯一元素(按顺序)
  • 对于每个唯一的元素,打印它,包括一个空格 ( print "#{e} ")
  • 一旦我们完成了独特的元素,就打印一个换行符