代码之家  ›  专栏  ›  技术社区  ›  Jaeyoung Park

[SED/AWK]交换值

  •  2
  • Jaeyoung Park  · 技术社区  · 7 年前

    我想交换列(或()中的变量)。如果一行以“FD1”开头,则()中的变量需要向右移动。最右边的变量转到最左边。

    例如,FD1 DFF_0(CK、G5、G10)--&燃气轮机;FD1 DFF_0(G10,CK,G5);

    我的文件。txt:

      FD1 DFF_0(CK,G5,G10);
      FD1 DFF_1(CK,G6,G11);
      IV  NOT_0(G14,G0);
      IV  NOT_1(G17,G11);
      AN2 AND2_0(G8,G14,G6);
      ND2 NAND2_0(G9,G16,G15);
      NR2 NOR2_0(G10,G14,G11);
      NR2 NOR2_1(G11,G5,G9);
    

    输出文件。txt:

      FD1 DFF_0(G10,CK,G5);
      FD1 DFF_1(G11,CK,G6);
      IV  NOT_0(G0,G14);
      IV  NOT_1(G11,G17);
      AN2 AND2_0(G14,G6,G8);
      ND2 NAND2_0(G16,G15,G9);
      NR2 NOR2_0(G14,G11,G10);
      NR2 NOR2_1(G5,G9,G11);
    

    我知道一个基本的SED,可以在全局范围内替换SED的s/original/new/g文件。但是我认为我的问题是一个条件转换。

    感谢您的帮助。

    3 回复  |  直到 7 年前
        1
  •  2
  •   RavinderSingh13 Nikita Bakshi    7 年前

    解决方案1: 如果只想对从字符串开始的行进行更改 FD1

    awk -F'[),(]' '              ##Creating ) comma and ( as field separators in each line of Input_file here by -F option of awk.
    /^FD1/{                      ##Checking if a line starts from FD1 then do following.
     print $1"("$4","$2","$3");";##Printing the 1st column then ( then 4th column , 2nd column , 3rd column. I will explain further how columns will be seen here in another snippt of code.
     next                        ##next will skip all further statements.
    }
    1                            ##Mentioning 1 will print the lines.
    ' Input_file                 ##Mentioning the Input_file name here.
    

    如何看到字段的编号如下,这样你就可以理解上面打印的东西了。 为了让你们明白,我只跑了第一条线。

    awk -F'[),(]' 'NR==1{for(i=1;i<=NF;i++){print "field number:",i OFS "field value:",$i}}'  Input_file
    field number: 1 field value: FD1 DFF_0
    field number: 2 field value: CK
    field number: 3 field value: G5
    field number: 4 field value: G10
    field number: 5 field value: ;
    

    如果您想对所有行进行更改,那么下面的内容可能会对您有所帮助。

    awk -F'[),(]' '               ##Creating ) comma and ( as field separators in each line of Input_file here by -F option of awk.
    NF==5{                        ##Checking if number of fields in a line are 5.
      print $1"("$4","$2","$3");";##Printing 1st field ( 4th field comma 2nd field comma 3rd field ) here.
      next                        ##next is awk built-in variable which skips all further statements.
    }
    NF==4{                        ##Checking if number of fields are 4 in a line.
      print $1"("$3","$2");";     ##printing $1 ( $3 comma $2 ); here.
    }'   Input_file               ##Mentioning Input_file name here.
    

    此外,如果您想将输出保存到Input_文件本身,请附加 > temp_file && mv temp_file Input_file 到上面的代码,然后它应该飞。

        2
  •  1
  •   karakfa    7 年前

    awk 为救援干杯!

    awk -F'[()]' 'function rotateLeft(x) 
                      {return gensub(/([^,]+),(.*)/,"\\2,\\1",1,x)}
                  function rotateRight(x) 
                      {return gensub(/(.*),([^,]+)/,"\\2,\\1",1,x)}
    
                 {print $1 "(" (/^FD1/?rotateRight($2):rotateLeft($2)) ")" $3}'
    
    FD1 DFF_0(G10,CK,G5);
    FD1 DFF_1(G11,CK,G6);
    IV  NOT_0(G0,G14);
    IV  NOT_1(G11,G17);
    AN2 AND2_0(G14,G6,G8);
    ND2 NAND2_0(G16,G15,G9);
    NR2 NOR2_0(G14,G11,G10);
    NR2 NOR2_1(G5,G9,G11);
    

    更新

    这样可能更简单

    $ awk -F'[()]' 'function rotate(left,x) {
                      one="([^,]+)"
                      rest="(.*)"
                      regex=left?(rest "," one):(one "," rest);
                      return gensub(regex,"\\2,\\1",1,x)}
    
                    {print $1 "(" rotate(/^FD1/,$2) ")" $3}' file
    
        3
  •  1
  •   Carl Smith    7 年前
    sed -n -r -e '/^FD1/s/\((.*),([^,]*)\)/(\2,\1)/p' -e '/^FD1/!s/\(([^,]*),(.*)\)/(\2,\1)/p' Myfile.txt