我有以下内容:
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/