删除文件每一行的重复项

删除文件每一行的重复项

我怎样才能删除每行中的重复项,例如这里?

1 1 1 2 1 2 3
5 5 4 1 2 3 3

我想获得这个输出:

1 2 3 
5 4 1 2 3

有很多行(100,000),并且我希望每行都有唯一的值。Perl 可能是最快的,但是如何在 Perl 或 Bash 中做到这一点?

答案1

以下是使用 awk 的一个选项:

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

编辑更新了评论:

  1. while (++i<=NF)

    初始化 while 循环,由于 $0 是 awk 中的完整行,因此预先增加“i”。

    因此它从 $1(第一个字段)开始。循环遍历行直到行末(小于或等于 awk 中内置的“字段数”的“NF”)。默认字段分隔符是空格,您可以轻松更改默认分隔符。

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

    这是一个三元运算

    因此,如果输入不在数组中!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

答案2

由于ruby我所知道的任何 Linux 发行版都附带:

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

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

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

  • 读取输入(来自< test你的 shell)
  • 浏览输入的每一行
  • 根据分隔项之间的一个空格将行拆分为数组 ( split(" "))
  • 从该数组中获取唯一元素(按顺序)
  • 对于每个唯一元素,打印它,包括空格(print "#{e} "
  • 处理完唯一元素后,打印换行符

答案3

不是纯粹的 bash,但是...:

while read line; do
    printf "%s\n" $line | sort -u | tr '\n' ' '
    echo ''
done < file

这些行将作为副产品进行分类。

相关内容