在 awk 中处理具有多个 delims 的文本

Processing text with multiple delims in awk

我有一段文字看起来像 -

Application.||dates:[2022-11-12]|models:[MODEL1]|count:1|ids:2320 
Application.||dates:[2022-11-12]|models:[MODEL1]|count:5|ids:2320 

我想要 count:1 列中的数字,所以 1 我希望将这些数字存储在一个数组中。

nums=($(echo -n "$grepResult" | awk -F ':' '{ print  }' | awk -F '|' '{ print  }'))

这看起来很重复而且效率不高,有什么想法可以简化这个吗?

试试 sed

nums=($(sed 's/.*count://;s/|.*//' <<< "$grepResult"))

解释:
有两个用 ; 分隔的 sed 命令。符号。
第一个命令 's/.*count://' 删除所有字符,直到 'count:' 包括它。
第二个命令 's/|.*//' 删除从 '|' 开始的所有字符,包括它。
命令顺序在这里很重要。

你可以使用awk一次,将字段分隔符设置为|。然后循环所有字段并拆分 :

如果字段以 count 开头,则打印拆分值的第二部分。

这样 count: 部分可以出现在字符串中的任何位置,并且可以打印多次。

nums=($(echo -n "$grepResult" |  awk -F'|' '
{
  for(i=1; i<=NF; i++) {
    split($i, a, ":")
    if (a[1] == "count") {
      print a[2]
    }
  }
}
'))

for i in "${nums[@]}"
do
   echo "$i"
done

输出

1
5

如果要合并两个拆分值,可​​以使用 [|:] 作为字符 class 并打印字段编号 8 以实现评论中提到的精确匹配。

请注意,它不会检查它是否以 count:

开头
 nums=($(echo -n "$grepResult" |  awk -F '[|:]' '{print }'))

使用 gnu awk 您可以使用捕获组来获得更精确的匹配,其中左侧和右侧可以是字符串的 start/end 或管道字符。第二组匹配1个或多个数字:

nums=($(echo -n "$grepResult" | awk 'match([=13=], /(^|\|)count:([0-9]+)(\||$)/, a) {print a[2]}' ))