uniq -c 相当于任意计数的行组

uniq -c 相当于任意计数的行组

我有一个约 1-2 百万行的文件,我试图通过计算重复的行组来减少该文件,并保留顺序。

uniq -c工作正常:

$ perl -E 'say for (("foo") x 4, ("bar") x 4, "baz", ("foo", "bar", "baz") x 4)' | uniq -c
      4 foo
      4 bar
      1 baz
      1 foo
      1 bar
      1 baz
      1 foo
      1 bar
      1 baz
      1 foo
      1 bar
      1 baz
      1 foo
      1 bar
      1 baz

在我的用例中(但不在下面的 foo-bar-baz 示例中),计数线路效率提高约 20%,如下所示:

$ perl -E 'say for (("foo") x 4, ("bar") x 4, "baz", ("foo", "bar", "baz") x 4)' \
  | sed 's/^/__STARTOFSTRINGDELIMITER__/' \
  | paste - - \
  | uniq -c \
  | sed -r 's/__STARTOFSTRINGDELIMITER__//; s/__STARTOFSTRINGDELIMITER__/\n\t/;'
      2 foo
        foo
      2 bar
        bar
      1 baz
        foo
      1 bar
        baz
      1 foo
        bar
      1 baz
        foo
      1 bar
        baz
      1 foo
        bar
      1 baz

(这种格式我可以接受。)

如何将任意行数的重复组(好吧,保持合理的缓冲区计数,如 2-10 行)减少到单个副本 + 行数?

按照上面的示例,我希望输出类似于:

4 foo
4 bar
1 baz
4 foo
  bar
  baz

答案1

我没有这么大的数据集来进行基准测试。尝试一下:

$ perl -E 'say for (("foo") x 4, ("bar") x 4, "baz", ("foo", "bar", "baz") x 4)' | awk 'NR == 1 {word=$0; count=1; next} $0 != word {print count,word; word=$0; count=1; next} { count++ } END { print count,word }'
4 foo
4 bar
1 baz
1 foo
1 bar
1 baz
1 foo
1 bar
1 baz
1 foo
1 bar
1 baz
1 foo
1 bar
1 baz

使用mawk代替awk可以提高性能。

相关内容