【问题标题】:Why uniq -c output with space instead of \t?为什么 uniq -c 输出带有空格而不是 \t?
【发布时间】:2012-07-26 13:29:41
【问题描述】:

我使用 uniq -c 一些文本文件。 它的输出是这样的:

123(space)first word(tab)other things
  2(space)second word(tab)other things

....

所以我需要提取总数(如上面的 123 和 2),但我不知道怎么做,因为如果我用空格分割这一行,它会像这样['123', 'first', 'word(tab)other', 'things']。 我想知道为什么不带tab输出?

以及如何提取shell中的总数? (我终于用python解压了,WTF)

更新:抱歉,我没有正确描述我的问题。我不想将总数相加,我只想将(空格)替换为(制表符),但这不会影响单词中的空格,因为我仍然需要后面的数据。就像这样:

123(tab)first word(tab)other things
  2(tab)second word(tab)other things

【问题讨论】:

  • 制表符不是空格,所以 awk 是正确的。
  • @Tichodroma 不,你没有关注我。我的意思是如果我按空格分割行,我无法正确获取数据。

标签: shell awk uniq


【解决方案1】:

试试这个:

uniq -c | sed -r 's/^( *[^ ]+) +/\1\t/'

【讨论】:

  • 这就是我想要的!谢谢大家。我忘了我终于可以输掉/g了。
【解决方案2】:

试试:

uniq -c text.file | sed -e 's/ *//' -e 's/ /\t/'

这将删除行数之前的空格,然后只用制表符替换第一个空格。

要将所有空格替换为制表符,请使用 tr:

uniq -c text.file | tr ' ' '\t'

要用单个选项卡替换所有连续运行的选项卡,请使用 -s:

uniq -c text.file | tr -s ' ' '\t'

【讨论】:

    【解决方案3】:

    您可以使用awk 对所有数字求和:

    awk '{s+=$1}END{print s}'
    

    【讨论】:

      【解决方案4】:
      $ cat <file> | uniq -c | awk -F" " '{sum += $1} END {print sum}'
      

      【讨论】:

      • 看看cat one-file的任何出现;它可以用 I/O 重定向代替。甚至还有UUOC 奖。
      • 关于 Unix 的另一个好处是如何使用管道保持代码整洁和结构良好。当然,您可以使用重定向而不是 cat file,但以这种形式进行说明/解释(甚至生产编码也是如此)是完全合理的,因为在实践中它通常最终会成为一个更复杂的命令,从而启动事情.性能论点也似是而非。大多数时候它实际上并不重要,你最好优化可读性。
      • 是的,我通常用它作为其他一些进程的占位符,在这样的在线给出示例时打印到标准输出。
      【解决方案5】:

      在计数后获取选项卡的一种可能解决方案是编写一个类似于uniq -c 的脚本,该脚本完全按照您的需要进行格式化。这是一个快速尝试(这似乎通过了我大约一分钟的测试):

      awk '
      (NR == 1) || ($0 != lastLine) {
          if (NR != 1) {
              printf("%d\t%s\n", count, lastLine);
          }
          lastLine = $0;
          count = 1;
          next;
      }
      {
          count++;
      }
      END {
          printf("%d\t%s\n", count, lastLine);
      }
      ' yourFile.txt
      

      【讨论】:

        【解决方案6】:

        另一种解决方案。这相当于早期的sed 解决方案,但它确实按照请求/标记使用awk

        cat yourFile.txt \
            | uniq -c \
            | awk '{
                match($0, /^ *[^ ]* /);
                printf("%s\t%s\n", $1, substr($0, RLENGTH + 1));
              }'
        

        【讨论】:

          【解决方案7】:

          基于 William Pursell answer ,如果你喜欢 Perl 兼容的正则表达式 (PCRE),也许更优雅和现代的方式会是

          perl -pe 's/ *(\d+) /$1\t/'
          

          选项是to execute (-e) and print (-p)

          【讨论】:

            猜你喜欢
            • 2020-09-19
            • 1970-01-01
            • 2017-04-01
            • 2011-05-12
            • 1970-01-01
            • 2017-08-17
            • 2011-09-20
            • 1970-01-01
            • 2020-02-10
            相关资源
            最近更新 更多