【问题标题】:Using awk to extract data and count使用awk提取数据并计数
【发布时间】:2017-04-17 00:51:48
【问题描述】:

如何在如下所示的文件上使用 awk:

abcd Z
efdg Z
aqbs F
edf  F
aasd A

我想提取字母表中每个字母出现在第二列的次数,所以输出应该是:

Z 2
F 2
A 1

【问题讨论】:

  • sed 用于在单个行上进行简单替换,仅此而已。在许多事情中 sed 不适合您,可以包括计数或任何其他类型的算术。那么 - 除了 awk 之外,您为什么还要 sed 解决方案来解决显然是 awk 应用程序的问题?
  • 从标签列表和问题描述中删除sed标签(没有理由结合sedawk)以获得快速解决方案

标签: linux unix awk


【解决方案1】:

尝试:如果您希望输出顺序与 Input_file 相同,那么以下内容可能会对您有所帮助。

awk 'FNR==NR{A[$2]++;next} A[$2]{print $2,A[$2];delete A[$2]}'   Input_file  Input_file

如果您不介意 2 美元的订单,那么以下可能会对您有所帮助。

awk '{A[$2]++} END{for(i in A){print i,A[i]}}'   Input_file

在第一个解决方案中,两次读取 Input_file 并创建一个数组 A,其索引为 $2,其递增值。然后当第二个 Input_file 被读取时,然后打印 $2 并且它是计数的。 在第二个解决方案中,创建一个数组 A,其索引为 $2 并递增它的值。然后在最后部分遍历数组 A 并打印它的索引和数组 A 的值。

【讨论】:

    【解决方案2】:

    我会为此使用sort | uniq,因为这两个实用程序是专门为此类任务设计的:

    cat <<END | 
    abcd Z
    efdg Z
    aqbs F
    edf  F
    aasd A
    END
    awk '{print $2}' | sort -r | uniq -c | awk '{printf "%s %d\n", $2, $1}'
    

    会产生完全期望的输出

    Z 2
    F 2
    A 1
    

    这里awk '{print $2}' 用于从文档中获取第二列,其中字段由一个或多个空格字符分隔。如果我们知道列的宽度是固定的,我们可以改用更快的cut 实用程序。

    sort -r | uniq -c 正在执行任务的主要算法部分 - 以相反的顺序对字母进行排序并计算每个字母出现的次数。

    awk '{printf "%s %d\n", $2, $1}'uniq -c 输出进行一些重新格式化以完全匹配所需的格式。

    更新: AWK 具有强大的数组支持,因此可以单独使用 awk 完成:

    cat <<END | 
    abcd Z
    efdg Z
    aqbs F
    edf  F
    aasd A
    END
    awk '{a[$2]++} 
         END {n=asorti(a,b,"@ind_str_desc"); 
         for (k=1;k<=n;k++) {printf b[k], a[b[k]]} }'
    

    我们使用数组a,它以输入流中的字母为索引,并且在每一行中,由相应字母索引的元素递增。

    END 子句中,我们颠倒索引的顺序并输出数组。

    【讨论】:

    • 可以只使用 awk 和 wc 来完成,别无其他。 awk 和 grep -c 怎么样
    • @identical123456 是的,这可以单独用 awk 完成,我已经更新了帖子。
    • asorti() 没有做任何有用的事情,它只是使脚本不必要地特定于 gawk。您将数组a 排序到数组b 中,然后由in 运算符以随机(通常是散列)顺序访问b 的索引。也没有理由认为任何特定的排序顺序都是可取的,如果输出顺序应该模仿输入顺序,那么这需要一种不同的方法来跟踪出现在输入中的键值。也没有理由在这种情况下使用 printf 而不是只使用 print。
    • @EdMorton 将基于in 的枚举替换为显式迭代。这应该确保输出中字母的顺序是降序的。我同意此要求未在 OP 中说明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多