为gsub动态生成的正则表达式无法正常工作

时间:2017-03-05 17:34:57

标签: regex awk gsub

我有一个输入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

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