Jaeyoung Park
Jaeyoung Park

Reputation: 339

[SED/AWK]exchange values

I would like to exchange columns (or variables in ( )). If a line starts with "FD1", variables in () need to shift toward the right. The rightmost variable goes to the leftmost.

For example, FD1 DFF_0(CK,G5,G10); --> FD1 DFF_0(G10,CK,G5);

For the other lines, variables in () need to shift toward the left.

Myfile.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);

Outfile.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);

I know a basic of SED that can replace globally, sed 's/original/new/g' file.txt, but I think my problem is a conditional shift.

Any help is appreciated.

Upvotes: 2

Views: 117

Answers (3)

karakfa
karakfa

Reputation: 67467

awk to the rescue!

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);

UPDATE

Perhaps simpler this way

$ 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

Upvotes: 1

RavinderSingh13
RavinderSingh13

Reputation: 133458

Solution 1st: If you want to make the changes only for the lines which start from string FD1 then following may help you on same.

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.

How to see the field's with their number as follows, so that you can understand above printing thing. I am running only for very first line to make you understand.

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: ;

Solution 2nd: If you want to make changes on all of the lines then following may help you on same.

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.

Also in case if you want to save the output into Input_file itself then append > temp_file && mv temp_file Input_file to above codes and it should fly then.

Upvotes: 2

Carl Smith
Carl Smith

Reputation: 728

sed -n -r -e '/^FD1/s/\((.*),([^,]*)\)/(\2,\1)/p' -e '/^FD1/!s/\(([^,]*),(.*)\)/(\2,\1)/p' Myfile.txt

Upvotes: 1

Related Questions