【问题标题】:Linux: Extract and transform attributes from lineLinux:从行中提取和转换属性
【发布时间】:2012-10-25 13:46:54
【问题描述】:

如果有文件,行格式如下:

SOME_ATTRIBUTE_1 XYZ; IMPORTANT_ATTRIBUTE_1 1234; SOME_ATTRIBUTE_2 XYZ; IMPORTANT_ATTRIBUTE_2 AB;

现在我想把它转换成下面的形式,两个重要的属性值产生一个新的属性:

JOIN_IMPORTANT_ATTRIBUTE AB1234; SOME_ATTRIBUTE_1 XYZ; IMPORTANT_ATTRIBUTE_1 1234; SOME_ATTRIBUTE_2 XYZ; IMPORTANT_ATTRIBUTE_2 AB;

这可以用 awk 或类似的单行代码来完成吗?我不知道如何解决这个问题,而不是抓住 java 技巧。

【问题讨论】:

    标签: regex linux shell awk nawk


    【解决方案1】:

    使用 awk,您可以将输入拆分为分号 + 任意数量的空格,并进一步拆分重要字段,如下所示:

    awk -F'; *' '{ split($2, a1, / +/); split($4, a2, / +/); print "JOIN_IMPORTANT_ATTRIBUTE", a2[2] a1[2] ";", $0 }' infile 
    

    输出:

    JOIN_IMPORTANT_ATTRIBUTE AB1234; SOME_ATTRIBUTE_1 XYZ; IMPORTANT_ATTRIBUTE_1 1234; SOME_ATTRIBUTE_2 XYZ; IMPORTANT_ATTRIBUTE_2 AB;
    

    这假设您知道重要属性所在的列。

    【讨论】:

      【解决方案2】:
      awk -F'[; ]+' '{print "JOIN_IMPORTANT_ATTRIBUTE", $8 $4 "; " $0}' file
      

      【讨论】:

        【解决方案3】:

        Perl 解决方案:

        perl -lane 'print join " ", "JOIN_IMPORTANT_ATTRIBUTE", substr($F[7], 0, -1) . $F[3], @F' 
        

        【讨论】:

          【解决方案4】:

          这是我的 bash+awk 替代方案。

          cat attrs.awk
          # Awk script to get joined attributes for one line of attributes
          
          BEGIN {
          RS=";";     
          PROCINFO["sorted_in"]="@ind_num_asc"; #gawk only: sort attributes on their attr id (so that IMPORTANT_ATTRIBUTE_n comes before IMPORTANT_ATTRIBUTE_n+1
          }
          
          $1 ~ /^IMPORTANT_ATTRIBUTE_/ {
                      attrId=substr($1, 1 + length("IMPORTANT_ATTRIBUTE_"));
              if ($2 ~ /^[0-9]/) 
                      impAttrsNum[attrId]=$2;
              else
                      impAttrsAlpha[attrId]=$2;
          }
          
          END {
              #alpha attribs come before num attribs
              for(i in impAttrsAlpha)
                      alphaVals = alphaVals impAttrsAlpha[i];
              for(i in impAttrsNum)
                      numVals = numVals impAttrsNum[i];
          
              printf("JOIN_IMPORTANT_ATTRIBUTE %s%s%s", alphaVals, numVals, RS);
          }
          
          cat joinattrs
          #!/bin/bash
          #
          # Applies joined attributes for each input line
          
          while read l
          do
              if [[ -n "$l" ]]
              then   
                      joinAttrs=$(echo "$l" | awk -f attrs.awk)
                      echo "$joinAttrs $l"
              fi
          done  
          

          使用方法: ./joinattrs

          不是单行的:)

          【讨论】:

            猜你喜欢
            • 2011-11-15
            • 1970-01-01
            • 1970-01-01
            • 2017-01-13
            • 1970-01-01
            • 2021-03-24
            • 2021-03-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多