我有以下内容:
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
答案 0 :(得分:2)
你刚刚调用了错误的函数,你应该使用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个arg分割()就像你使用GNU awk为第3个arg匹配()。
如果你必须在非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
答案 1 :(得分:1)
match
的结果可用于获取不匹配的部分
附加匹配:
{
for (s = $0; match(s, /ZZ:Z[^ ]*/);
s = substr(s, RSTART + RLENGTH, length))
printf("%s%s", s == $0 ? "" : " ",
substr(s, RSTART, RLENGTH))
print ""
}
或者,可以在唯一标识符上拆分字符串,
使用split
或FS
:
{
l = split($0, a, /ZZ:Z/)
for(i = 2; i <= l; i++)
printf("%s%s", i == 2 ? "" : " ",
"ZZ:Z" substr(a[i], 1, index(a[i], " ") - 1))
print ""
}
答案 2 :(得分:0)
谢谢,上述解决方案非常棒,无论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[^ ]*).*(ZZ:Z[^ ]*).*/,"\\1 \\2","g");print val}'
输出:
ZZ:Z:mus.sup ZZ:Z:cas.sup
此外,这是解决方案 - 使用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[^ ]*).*(ZZ:Z[^ ]*).*/,m); print m[1], m[2]}'