拆分数组并将值发送到 awk 中的哈希集

拆分数组并将值发送到 awk 中的哈希集

我将 var 作为从 shell 脚本到 awk 的参数

awk -v var = "blah1|blah2|blah3" -f awk_script.awk

我需要将每个废话放入哈希集中,目前,我正在这样做。我将它放入一个数组中并循环遍历该数组并将其放入哈希集中。我可以做得更好,比如获取 var 并将变量直接放入哈希集中,而不是先将 var 解析到数组中吗?

    split(var,arr,"|");
    for ( i = 1; i <= length(arr); i++ )
    {
            dest = arr[i];
            exclusion_destinations[dest];
    }

下线,我检查

if ( dest in exclusion_destinations )
{
// do something
}

答案1

一次设置多个数组元素的唯一构造是函数split(至少在标准 awk 中,GNU awk 可能有其他可能性)。这分配给数字索引。所以如果你想创建一个关联数组,你就无法逃脱循环。

但是,您可以更改排除测试以不使用数组。如果要排除的字符串不包含任何正则表达式特殊字符 ( ().?*+[]\^$),您可以将 的值视为var要匹配的正则表达式,只需稍加调整即可。这可能比使用数组稍慢,但可能不会明显慢,除非您有很多字符串要排除。

BEGIN { exclude = "^(" var ")$" }
match(dest, exclude) { … }

另一种方法是将其var视为要排除的字符串串联;如果 is 出现在之间,dest则被排除。这将再次比正则表达式匹配慢,但仅对于足够大的排除列表而言才可测量。var|

BEGIN { exclude = "|" var "|" }
index(dest, exclude) { … }

答案2

我假设你的第二个“下线”dest 来自输入文件,其中包含您对照排除值检查的值(例如,将此输入文件称为“数据”)。
您可以通过另一个文件(例如称为“排除”)读取排除值列表。如果排除已经由 分隔|,只需使用 sed 将它们更改为\n.

创建测试文件

sed 's/ /\n/g' <<<"blah1 blah2 abcde" >data
sed 's/|/\n/g' <<<"blah1|blah2|blah3" >exclude

剧本

awk '{
  if( NR==FNR ) { exclude[$0]++ 
  }else{ 

    # somewhere later on
    # "dest" to be tested is $1 of "data"
    if( exclude[$1] ) print "do something", $1 
  }
}' exclude data

或者像这样传递两个“文件”可能适合:

}' <(sed 's/|/\n/g' <<<"blah1|blah2|blah3") \
   data  

输出

do something blah1
do something blah2

相关内容