我有一个输入CSV文件:
1,5,1
1,6,2
1,5,3
1,7,4
1,5,5
1,6,6
1,6,7
我需要按如下方式创建一个字符串:
;5,1,3,5;6,2,6,7;7,4
因此$2
之间的子串中的每个字符(除了第一个字段;
的值之外)表示中间字段的行号;例如;5,1,3,5
表示5
位于行号1,3,5
。
我一直试图将awk与gsub
一起使用,尝试动态创建字符串MYSTR
。
gsub
内的正则表达式无效。我需要一个匹配;$3
的正则表达式($3
的值,可以是两位数)并将其替换为;$3,RowNO
,如果模式不匹配则添加{{ 1}}在字符串的末尾。
这是我到目前为止所做的:
;$3
答案 0 :(得分:0)
正则表达式不起作用,因为$3
不被解释为字段#3值,但被视为锚$
(与行尾相匹配)和文字3
。
您可以在没有gsub
的情况下执行此操作:
awk -F, '{a[$2]=a[$2]","NR}END{for (i in a){printf(";%d%s",i,a[i])}}'
答案 1 :(得分:0)
<强>输入强>
$ cat file
1,5,1
1,6,2
1,5,3
1,7,4
1,5,5
1,6,6
1,6,7
<强>输出强>
$ awk -F, '{gsub(/[ ]+/,"",$3);a[$2] = ($2 in a ? a[$2]:$2) FS $3 }END{for(i in a)printf("%s%s",";",a[i]); print ""}' file
;5,1,3,5;6,2,6,7;7,4
更好的可读版本
awk -F, '
{
gsub(/[ ]+/,"",$3); # suppress space char in third field
a[$2] = ($2 in a ? a[$2]:$2) FS $3 # array a where index being field2 and value will be field3, if index exists before append string with existing value
}
END{
for(i in a) # loop through array a and print values
printf("%s%s",";",a[i]);
print ""
}
' file
答案 2 :(得分:0)
@vsshekhar:请尝试关注:它将以与Input_file($ 2)相同的顺序为您提供值。
awk -F, '{A[++i]=$2;B[A[i]]=B[A[i]]?B[A[i]] "," FNR:FNR} END{for(j=1;j<=i;j++){if(B[A[j]]){printf(";%s,%s",A[j],B[A[j]]);delete B[A[j]]}};print ""}' Input_file
现在也添加非单线形式的解决方案。
awk -F, '{
A[++i]=$2;
B[A[i]]=B[A[i]]?B[A[i]] "," FNR:FNR
}
END{
for(j=1;j<=i;j++){
if(B[A[j]]){
printf(";%s,%s",A[j],B[A[j]]);
delete B[A[j]]
}
};
print ""
}
' Input_file