【问题标题】:Check if an awk array contains a value检查 awk 数组是否包含值
【发布时间】:2015-01-01 00:07:29
【问题描述】:

使用 Perl,您可以检查数组是否包含值

$ perl -e '@foo=(444,555,666); print 555 ~~ @foo ? "T" : "F"'
T

但是对于 awk,这个类似的命令是检查数组索引而不是 价值观

$ awk 'BEGIN {split("444 555 666", foo); print 555 in foo ? "T" : "F"}'
F

如何使用 awk 检查数组是否包含特定值?

【问题讨论】:

  • 我相信你唯一的选择就是循环播放。
  • 就像 Etan 说的,你需要一个 for 循环。您可以通过创建一个以值作为键的新数组(哈希)来获得一些灵活的结果,例如:awk 'BEGIN { split("444 555 666", foo); for(i=1; i<=length(foo); i++) bar[foo[i]]; print 555 in bar ? "T" : "F" }'
  • @Thor - 你不能用for( i in foo ) bar[foo[i]] 代替吗?
  • @n0741337:你是对的,更短更干净,所以它变成:awk 'BEGIN { split("444 555 666", foo); for(i in foo) bar[foo[i]]; print 555 in bar ? "T" : "F" }'

标签: arrays awk


【解决方案1】:

这里的菜鸟。我消化了Steven's answer,最后得到了这个希望更容易理解的sn-p。还有两个更微妙的问题:

  • Awk 数组实际上是一个字典。不是["value1", "value2"],更像是{0: "value1", 1: "value2"}
  • in 检查键,没有内置的方法检查值。

所以你必须将你的数组(实际上是一个字典)转换为一个以值作为键的字典。

BEGIN {

    split("value1 value2", valuesAsValues)
    # valuesAsValues = {0: "value1", 1: "value2"}

    for (i in valuesAsValues) valuesAsKeys[valuesAsValues[i]] = ""
    # valuesAsKeys = {"value1": "", "value2": ""}
}

# Now you can use `in`
($1 in valuesAsKeys) {print}

对于单行:

echo "A:B:C:D:E:F" | tr ':' '\n' | \
awk 'BEGIN{ split("A D F", parts); for (i in parts) dict[parts[i]]=""}  $1 in dict'

【讨论】:

    【解决方案2】:

    我所做的是构建我的数据以利用语言提供的优势。

    所以不要说:

    BEGIN {split("444 555 666", foo); .... }
    

    说:

    BEGIN { bar[ "444" ] ; ... }
    

    或者其他建议:

    BEGIN { 
      split("444 555 666", foo);
      for( i in FOO ) bar[foo[i]];
    }
    

    记住 awk 中的数组实际上是关联数组。

    【讨论】:

      猜你喜欢
      • 2019-08-10
      • 2021-07-15
      • 1970-01-01
      • 2016-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-06
      • 1970-01-01
      相关资源
      最近更新 更多