awk match() 多重匹配

标签 awk match

我有以下内容:

echo AS:i:0  UQ:i:0  ZZ:Z:mus.sup  NM:i:0  MD:Z:50  ZZ:Z:cas.sup  CO:Z:endOfLine|awk '{match($0,/ZZ:Z[^ ]*/,m); print m[0], m[1]}' 

不幸的是,它只输出第一个条目(两个中的一个):

ZZ:Z:mus.sup 

在我看来,match() 函数无法将多个匹配项存储到其数组中。除非我在这里遗漏了什么......?

如果情况确实如此,有人会建议一个基于 awk 的“匹配”替代方案,该替代方案将允许获得两个 ZZ:Z 条目。请注意,它们并非每次都位于同一列 (!) - 因此需要使用 match() 函数。

这里的一般想法是在同一个 awk 命令中获取一些出现在已知列位置(例如 col1、col2)的值,以及一些位于未知列的值(根据其唯一签名“ZZ:Z 获取”)索引列。

此外,以下尝试 - 使用 gensub() 也无法输出/打印两个 ZZ:Z 条目,并且仅识别两个条目中的一个(以及另一个在弃用倒数时..)

echo AS:i:0  UQ:i:0  ZZ:Z:mus.sup  NM:i:0  MD:Z:50  ZZ:Z:cas.sup  CO:Z:endOfLine|awk '{val= gensub(/.*(ZZ:Z[^ ]*).*/,"\\1 \\2","g",$0);print val}'

本例中的结果是:

ZZ:Z:cas.sup

但我想得到的结果是:

ZZ:Z:mus.sup ZZ:Z:cas.sup 

最佳答案

你只是调用了错误的函数,你应该使用 split() 而不是 match():

$ echo AS:i:0  UQ:i:0  ZZ:Z:mus.sup  NM:i:0  MD:Z:50  ZZ:Z:cas.sup  CO:Z:endOfLine|
awk '{split($0,t,/ZZ:Z[^ ]*/,m); print m[1], m[2]}'
ZZ:Z:mus.sup ZZ:Z:cas.sup

或者按照它们在输入中出现的顺序打印任意数量的事件:

$ echo AS:i:0  UQ:i:0  ZZ:Z:mus.sup  NM:i:0  MD:Z:50  ZZ:Z:cas.sup  CO:Z:endOfLine|
awk '{split($0,t,/ZZ:Z[^ ]*/,m); for (i=1; i in m; i++) print m[i]}'
ZZ:Z:mus.sup
ZZ:Z:cas.sup

它使用 GNU awk 作为第 4 个参数来 split() 就像你使用 GNU awk 作为第 3 个参数来匹配 () 一样。

如果您必须在非 GNU awk 中执行此操作,它只是:

$ echo AS:i:0  UQ:i:0  ZZ:Z:mus.sup  NM:i:0  MD:Z:50  ZZ:Z:cas.sup  CO:Z:endOfLine|
awk '{while(match($0,/ZZ:Z[^ ]*/)) {print substr($0,RSTART,RLENGTH); $0=substr($0,RSTART+RLENGTH)}}'
ZZ:Z:mus.sup
ZZ:Z:cas.sup

关于awk match() 多重匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40569441/

相关文章:

regex - awk/sed/grep/perl 使用字段分隔符然后仅显示特定行

bash - grep (fgrep) bash 精确匹配行尾

rust - 如何分配给匹配分支内的匹配表达式中使用的变量?

JavaCC 使用输入作为 'token'

javascript - js-正则匹配数组和字符串

bash - 如何在单个 ssh 命令中使用 bash $(awk)?

linux - 2个文件之间的差异(awk)

regex - 带有正则表达式的字符串之间的 Grep 值

java - 使用正则表达式java匹配数字和字母/数字(按分隔)

c++ - Cygwin 的 cmake 与 CMAKE_SYSTEM_NAME 不匹配