通过使用可能的数组在 awk 中以困难模式分析两列来计数

Posted

技术标签:

【中文标题】通过使用可能的数组在 awk 中以困难模式分析两列来计数【英文标题】:Counting by analizing two column in difficult pattern in awk by using probably arrays 【发布时间】:2021-07-09 15:41:06 【问题描述】:

我有一个大问题。我尝试创建一个脚本,它计算一个特定的总和(水桥的总和没关系)。这是我数据文件的一小部分

POP62 SOL11
KAR1  SOL24
KAR5  SOL31
POP17 SOL42
POP15 SOL2
POP17 SOL2
KAR7  SOL42
KAR1  SOL11
KAR6  SOL31

在第一列中,我有带有数字的 POP 或 KAR,例如 KAR1、POP17 等。在第二列中,我总是使用带有数字的 SOL,但我最多有 2 个相同的 SOL(例如,我可以有最多2个SOL42或SOL11等,KAR和POP我可以有2个以上)。

现在是我想做的事情。 如果我发现同一个 SOL 与 both KAR 和 POP(无论数字)连接,我添加 1。例如:

KAR6  SOL5
POP8  SOL5

总和加一

在我的数据中

POP62 SOL11
KAR1  SOL24
KAR5  SOL31
POP17 SOL42
POP15 SOL2
POP17 SOL2
KAR7  SOL42
KAR1  SOL11
KAR6  SOL31

我应该有 sum = 2 ,因为

POP17 SOL42
KAR7  SOL42

POP62 SOL11
KAR1  SOL11

你知道怎么做吗?我考虑使用 NR=FNR 并遍历文件两次并检查 $2 中的重复可能通过使用数组,但接下来呢?

#!/bin/bash 
awk 'NR==FNR         ?? 
       some condition sum++  
       END             print sum' test1.txt, >> water_bridges_x2.txt

编辑解决方案 如果它是空的,我也会添加 0,因为我想打印 0 而不是 null

awk '

   s = $1
   sub(/[0-9]+$/, "", s)           # strip digits from end in var s
   if ($2 in map && map[$2] != s)  # if existing entry is not same 
      ++sum                        # increment sum
   map[$2] = s

END print sum+0' file

2

【问题讨论】:

使 SOLxy 成为关联数组(字典)中的 key,并将相应 KAR 和 POP 的数组作为字典中的 value .将整组数据放入字典后,遍历字典中的键,检查值数组中有多少元素。如果值数组具有所需元素(即至少一个 KAR 和一个 POP),则将结果加 1 【参考方案1】:

你可以试试这个awk:

awk '

   s = $1
   sub(/[0-9]+$/, "", s)           # strip digits from end in var s
   if ($2 in map && map[$2] != s)  # if existing entry is not same 
      ++sum                        # increment sum
   map[$2] = s

END print sum+0' file

2

【讨论】:

谢谢,剥离数字是个好主意!非常感谢,很棒的脚本,也感谢这个脚本上的 cmets。【参考方案2】:

使用您展示的示例,这是另一种方法。在 GNU awk 中编写和测试,应该可以在任何 awk 中工作。

awk '

  match($1,/^[a-zA-Z]+/)
  val=substr($1,RSTART,RLENGTH)
  if(($2 in arr) && arr[$2]!=val)
    sum++
  
  arr[$2]=val

END
  print sum

'  Input_file

【讨论】:

【参考方案3】:

与@anubhava 类似的答案:这将 GNU awk 用于多维数组:

gawk '
    sols[$2][substr($1,0,3)] = 1 
    END 
        for (sol in sols) 
            if ("POP" in sols[sol] && "KAR" in sols[sol]) 
                sum++
        print sum
    
' file

【讨论】:

【参考方案4】:

另一种解决方案

$ sed -E 's/[0-9]+ +/ /' file    |   # cleanup data
  sort -k2                       |   # sort by key
  uniq                           |   # remove dups
  uniq -c -f1                    |   # count by key
  egrep '^ +2 ' -c                   # report the sum where count is 2.

2

【讨论】:

以上是关于通过使用可能的数组在 awk 中以困难模式分析两列来计数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 shell(awk、sed 等)删除文件中的前两列

在php中以ul li格式解析树数据时遇到一些困难

使用awk比较两个不同文件中的两列

awk执行过程模式数组

如何选择可能使用 awk/sed 多次出现的两个标记模式之间的行

是否可以在iPhone中以编程方式启用热点模式?