Swapping columns in specific blocks

Hi all,

I hope all you guys have a great new year!

I am trying to swap 2 columns in a specific block of a file. The file format is:

   
  Startpoint: in11 (input port)
  Endpoint: out421 (output port)
  Path Group: (none)
  Path Type: max

  Point                                    Incr       Path
  ---------------------------------------------------------------
  input external delay                     0.00       0.00 r
  in11 (in)                                0.00       0.00 r
  Ckt432/A[7] (TopLevel432b)               0.00       0.00 r
  Ckt432/M1/A[7] (PriorityA)               0.00       0.00 r
  Ckt432/M1/U7/Y (INVX1_RVT)               0.03       0.03 f
  Ckt432/M5/U12/Y (OA21X1_RVT)             0.10       2.44 r
  Ckt432/M5/Chan[3] (DecodeChan)           0.00       2.44 r
  Ckt432/Chan[3] (TopLevel432b)            0.00       2.44 r
  out421 (out)                             0.00       2.44 r
  data arrival time                                   2.44
  ---------------------------------------------------------------
  (Path is unconstrained)


  Startpoint: in37 (input port)
  Endpoint: out421 (output port)
  Path Group: (none)
  Path Type: max

  Point                                    Incr       Path
  ---------------------------------------------------------------
  input external delay                     0.00       0.00 r
  in37 (in)                                0.00       0.00 r
  Ckt432/A[5] (TopLevel432b)               0.00       0.00 r
  Ckt432/M1/A[5] (PriorityA)               0.00       0.00 r
  Ckt432/M1/U8/Y (INVX1_RVT)               0.03       0.03 f
  Ckt432/M1/U13/Y (NAND2X0_RVT)            0.06       0.10 r
  Ckt432/M5/U12/Y (OA21X1_RVT)             0.10       2.44 r
  Ckt432/M5/Chan[3] (DecodeChan)           0.00       2.44 r
  Ckt432/Chan[3] (TopLevel432b)            0.00       2.44 r
  out421 (out)                             0.00       2.44 r
  data arrival time                                   2.44
  ---------------------------------------------------------------
  (Path is unconstrained) 

I am trying to
1) replace 5th column with 2nd column.
1-1) If a letter in 5th column is "r", this would be replaced with "v". If a letter in 5th column is "f", this would be replaced with "^".
2) insert two double quotation marks in 1st column.
3) replace 3rd column with ;
4) replace 4th column with //

This should only be done in blocks which are defined starting and ending lines - "input external delay" , "data arrival time".

Additionally, I want to change texts before/after the block with predefined texts. Before the block, I would like to add $path {
// from: in11
// to: out432
$name "test_1" ;
$cycle 1 ;
$slack -0.130978 ;
$transition {

After the block, I would like to add }
}

My expected output should be:

$path {
  // from: in11
  // to: out432
  $name "test_1" ;
  $cycle 1 ;
  $slack -0.130978 ;
  $transition {
 "in11"  v  ; //  (in)
 "Ckt432/A[7]"  v  ; //  (TopLevel432b)
 "Ckt432/M1/A[7]"  v  ; //  (PriorityA)
 "Ckt432/M1/U7/Y"  ^  ; //  (INVX1_RVT)
 "Ckt432/M5/U12/Y"  v  ; //  (OA21X1_RVT)
 "Ckt432/M5/Chan[3]"  v  ; //  (DecodeChan)
 "Ckt432/Chan[3]"  v  ; //  (TopLevel432b)
 "out421"  v  ; //  (out)
  }
}

$path {
  // from: in11
  // to: out432
  $name "test_2" ;
  $cycle 1 ;
  $slack -0.130978 ;
  $transition {
  "in37"  v  ; //  (in)
  "Ckt432/A[5]"  v  ; //  (TopLevel432b)
  "Ckt432/M1/A[5]"  v  ; //  (PriorityA)
  "Ckt432/M1/U8/Y"  ^  ; //  (INVX1_RVT)
  "Ckt432/M1/U13/Y"  v  ; //  (NAND2X0_RVT)
  "Ckt432/M5/U12/Y"  v  ; //  (OA21X1_RVT)
  "Ckt432/M5/Chan[3] "  v  ; //  (DecodeChan)
  "Ckt432/Chan[3] "  v  ; //  (TopLevel432b)
  "out421"  v  ; //  (out)
  }
}

Currently, I can swap columns, but I don't know how to use them only in the block. My code is:

awk ' { c1 = $1; c2 = $2; $1 = " \" "; $2 = c1; $3 = " \" "; $4 = $5; $5 = " ; // "; $6 = c2; print; } ' file1.txt

Any help you could give me will be greatly appreciated.

Would this do?

awk -v DQ="\"" '
/dat.*ime/      {IN = 0
                 print "}" RS "}"
                 next
                }
/inp.*lay/      {IN = 1
                 print  "$path {"                       RS \
                        "// from: in11"                 RS \
                        "// to: out432"                 RS \
                        "$name \"test_" ++CNT "\" ;"    RS \
                        "$cycle 1 ;"                    RS \
                        "$slack -0.130978 ;"            RS \
                        "$transition {"
                 next
                }

IN              {$1 = DQ $1 DQ
                 TM = $2
                 $2 = $5 == "r"?"v":"^"
                 $3 = ";"
                 $4 = "//"
                 $5 = TM
                 print
                }

' OFS="\t" file
$path {
// from: in11
// to: out432
$name "test_1" ;
$cycle 1 ;
$slack -0.130978 ;
$transition {
"in11"  v       ;       //      (in)
"Ckt432/A[7]"   v       ;       //      (TopLevel432b)
"Ckt432/M1/A[7]"        v       ;       //      (PriorityA)
"Ckt432/M1/U7/Y"        ^       ;       //      (INVX1_RVT)
"Ckt432/M5/U12/Y"       v       ;       //      (OA21X1_RVT)
"Ckt432/M5/Chan[3]"     v       ;       //      (DecodeChan)
"Ckt432/Chan[3]"        v       ;       //      (TopLevel432b)
"out421"        v       ;       //      (out)
}
}
$path {
// from: in11
// to: out432
$name "test_2" ;
$cycle 1 ;
$slack -0.130978 ;
$transition {
"in37"  v       ;       //      (in)
"Ckt432/A[5]"   v       ;       //      (TopLevel432b)
"Ckt432/M1/A[5]"        v       ;       //      (PriorityA)
"Ckt432/M1/U8/Y"        ^       ;       //      (INVX1_RVT)
"Ckt432/M1/U13/Y"       v       ;       //      (NAND2X0_RVT)
"Ckt432/M5/U12/Y"       v       ;       //      (OA21X1_RVT)
"Ckt432/M5/Chan[3]"     v       ;       //      (DecodeChan)
"Ckt432/Chan[3]"        v       ;       //      (TopLevel432b)
"out421"        v       ;       //      (out)
}
}

Hello jypark22,

Following may help you in same.

awk -vs1="\$path" -vs2="// from: in11" -vs3="// to: out432" -vs4="\$name "test_" ;" -vs5="\$cycle 1 ;" -vs6="\$slack -0.130978 ;" -vs7="\$transition {" -vs8="\"" '{VAR=s1 "\n" s2 "\n" s3 "\n" s4  "\n" s5 "\n" s6 "\n" s7};/ Point/{getline;getline;getline;while($0 !~ /Endpoint/){if($0 ~ /data arrival time/ || $0 ~ /Path is unconstrained/ || $0 ~ /^$/){;next};$1=s8 $1 s8;if($5 ~ /r/){$5="v"};if($5 ~ /f/){$5="^"};sub($3,";");sub($4,"//");E=$NF;$NF=$2;$2=E;S=S?S ORS $0:$0;getline}};/ Endpoint/{if(S){d++;sub(/test_/,"&" d,VAR);print VAR ORS S ORS " }" ORS "}" ORS;S=""}} END{d++;sub(/test_/,"&" d,VAR);print VAR ORS S ORS " }" ORS "}"}'   Input_file

Output will be as follows.

$path
// from: in11
// to: out432
$name test_1 ;
$cycle 1 ;
$slack -0.130978 ;
$transition {
"in11" v ; // (in)
"Ckt432/A[7]" v ; // (TopLevel432b)
"Ckt432/M1/A[7]" v ; // (PriorityA)
"Ckt432/M1/U7/Y" ^ ; // (INVX1_RVT)
"Ckt432/M5/U12/Y" v ; // (OA21X1_RVT)
"Ckt432/M5/Chan[3]" v ; // (DecodeChan)
"Ckt432/Chan[3]" v ; // (TopLevel432b)
"out421" v ; // (out)
 }
}
 $path
// from: in11
// to: out432
$name test_2 ;
$cycle 1 ;
$slack -0.130978 ;
$transition {
"in37" v ; // (in)
"Ckt432/A[5]" v ; // (TopLevel432b)
"Ckt432/M1/A[5]" v ; // (PriorityA)
"Ckt432/M1/U8/Y" ^ ; // (INVX1_RVT)
"Ckt432/M1/U13/Y" v ; // (NAND2X0_RVT)
"Ckt432/M5/U12/Y" v ; // (OA21X1_RVT)
"Ckt432/M5/Chan[3]" v ; // (DecodeChan)
"Ckt432/Chan[3]" v ; // (TopLevel432b)
"out421" v ; // (out)
 }
}

EDIT: Adding a non one-liner form for same solution too now.

awk -vs1="\$path" -vs2="// from: in11" -vs3="// to: out432" -vs4="\$name "test_" ;" -vs5="\$cycle 1 ;" -vs6="\$slack -0.130978 ;" -vs7="\$transition {" -vs8="\"" '{
VAR=s1 "\n" s2 "\n" s3 "\n" s4  "\n" s5 "\n" s6 "\n" s7};
/ Point/{
                getline;
                getline;
                getline;
                while($0 !~ /Endpoint/){
                                        if($0 ~ /data arrival time/ || $0 ~ /Path is unconstrained/ || $0 ~ /^$/){;
                                                                                                                        next
                                                                                                                 }
                ;$1=s8 $1 s8;
                if($5 ~ /r/)           {
                                        $5="v"
                                       };
                if($5 ~ /f/)           {
                                        $5="^"
                                       };
                sub($3,";");
                sub($4,"//");
                E=$NF;
                $NF=$2;
                $2=E;
                S=S?S ORS $0:$0;
                getline
                                       }
        };
/ Endpoint/{
                if(S)                  {
                                        d++;
                                        sub(/test_/,"&" d,VAR);
                                        print VAR ORS S ORS " }" ORS "}" ORS;
                                        S=""
                                       }
           }
END        {
                d++;
                sub(/test_/,"&" d,VAR);
                print VAR ORS S ORS " }" ORS "}"
           }'  Input_file
 

Output will be as follows.

$path
// from: in11
// to: out432
$name test_1 ;
$cycle 1 ;
$slack -0.130978 ;
$transition {
"in11" v ; // (in)
"Ckt432/A[7]" v ; // (TopLevel432b)
"Ckt432/M1/A[7]" v ; // (PriorityA)
"Ckt432/M1/U7/Y" ^ ; // (INVX1_RVT)
"Ckt432/M5/U12/Y" v ; // (OA21X1_RVT)
"Ckt432/M5/Chan[3]" v ; // (DecodeChan)
"Ckt432/Chan[3]" v ; // (TopLevel432b)
"out421" v ; // (out)
 }
}
$path
// from: in11
// to: out432
$name test_2 ;
$cycle 1 ;
$slack -0.130978 ;
$transition {
"in37" v ; // (in)
"Ckt432/A[5]" v ; // (TopLevel432b)
"Ckt432/M1/A[5]" v ; // (PriorityA)
"Ckt432/M1/U8/Y" ^ ; // (INVX1_RVT)
"Ckt432/M1/U13/Y" v ; // (NAND2X0_RVT)
"Ckt432/M5/U12/Y" v ; // (OA21X1_RVT)
"Ckt432/M5/Chan[3]" v ; // (DecodeChan)
"Ckt432/Chan[3]" v ; // (TopLevel432b)
"out421" v ; // (out)
 }
}
 

Thanks,
R. Singh

Here's a Perl version with the same indentation and extra space between blocks output, as hinted in the example posted.

perl -nle '
BEGIN{    
    %r=qw(f ^ r v);
    $addp1=q($path {
  // from: in11
  // to: out432
  $name "test_);
    $addp2=q(" ;
  $cycle 1 ;
  $slack -0.130978 ;
  $transition {);
    $addend=q(  }
});
    $start = "input external delay";
    $end = "data arrival time";
}

/$start/ and print $addp1 . ++$i . $addp2;
if(/$start/../$end/){
    print if s|^\s+([^\s]+)\s+(\(.*\)).*(\w)$|  "$1" $r{$3} ; // $2|;
};
/$end/ and print "$addend\n";
' jypark22.file
$path {
  // from: in11
  // to: out432
  $name "test_1" ;
  $cycle 1 ;
  $slack -0.130978 ;
  $transition {
  "in11" v ; // (in)
  "Ckt432/A[7]" v ; // (TopLevel432b)
  "Ckt432/M1/A[7]" v ; // (PriorityA)
  "Ckt432/M1/U7/Y" ^ ; // (INVX1_RVT)
  "Ckt432/M5/U12/Y" v ; // (OA21X1_RVT)
  "Ckt432/M5/Chan[3]" v ; // (DecodeChan)
  "Ckt432/Chan[3]" v ; // (TopLevel432b)
  "out421" v ; // (out)
  }
}

$path {
  // from: in11
  // to: out432
  $name "test_2" ;
  $cycle 1 ;
  $slack -0.130978 ;
  $transition {
  "in37" v ; // (in)
  "Ckt432/A[5]" v ; // (TopLevel432b)
  "Ckt432/M1/A[5]" v ; // (PriorityA)
  "Ckt432/M1/U8/Y" ^ ; // (INVX1_RVT)
  "Ckt432/M1/U13/Y" v ; // (NAND2X0_RVT)
  "Ckt432/M5/U12/Y" v ; // (OA21X1_RVT)
  "Ckt432/M5/Chan[3]" v ; // (DecodeChan)
  "Ckt432/Chan[3]" v ; // (TopLevel432b)
  "out421" v ; // (out)
  }
}

Here's a Python version:

$ 
$ cat input.txt

Startpoint: in11 (input port)
Endpoint: out421 (output port)
Path Group: (none)
Path Type: max

Point                                    Incr       Path
---------------------------------------------------------------
input external delay                     0.00       0.00 r
in11 (in)                                0.00       0.00 r
Ckt432/A[7] (TopLevel432b)               0.00       0.00 r
Ckt432/M1/A[7] (PriorityA)               0.00       0.00 r
Ckt432/M1/U7/Y (INVX1_RVT)               0.03       0.03 f
Ckt432/M5/U12/Y (OA21X1_RVT)             0.10       2.44 r
Ckt432/M5/Chan[3] (DecodeChan)           0.00       2.44 r
Ckt432/Chan[3] (TopLevel432b)            0.00       2.44 r
out421 (out)                             0.00       2.44 r
data arrival time                                   2.44
---------------------------------------------------------------
(Path is unconstrained)


Startpoint: in37 (input port)
Endpoint: out421 (output port)
Path Group: (none)
Path Type: max

Point                                    Incr       Path
---------------------------------------------------------------
input external delay                     0.00       0.00 r
in37 (in)                                0.00       0.00 r
Ckt432/A[5] (TopLevel432b)               0.00       0.00 r
Ckt432/M1/A[5] (PriorityA)               0.00       0.00 r
Ckt432/M1/U8/Y (INVX1_RVT)               0.03       0.03 f
Ckt432/M1/U13/Y (NAND2X0_RVT)            0.06       0.10 r
Ckt432/M5/U12/Y (OA21X1_RVT)             0.10       2.44 r
Ckt432/M5/Chan[3] (DecodeChan)           0.00       2.44 r
Ckt432/Chan[3] (TopLevel432b)            0.00       2.44 r
out421 (out)                             0.00       2.44 r
data arrival time                                   2.44
---------------------------------------------------------------
(Path is unconstrained)

$ 
$ cat -n process_input.py
     1	#!/usr/bin/env python
     2	# Usage: python process_input.py <input_file_name>
     3	
     4	from sys import argv
     5	input_file = argv[1]
     6	start_template = '''$path {
     7	  // from: in11
     8	  // to: out432
     9	  $name "test_#" ;
    10	  $cycle 1 ;
    11	  $slack -0.130978 ;
    12	  $transition {'''
    13	
    14	end_template = '''  }
    15	}
    16	'''
    17	
    18	inside_block = 0
    19	iter = 0
    20	chunk = []
    21	for line in open(input_file, 'rt'):
    22	    if line.startswith('input external delay'):
    23	        inside_block = 1
    24	        iter += 1
    25	        chunk.append(start_template.replace('#', str(iter)))
    26	    elif line.startswith('data arrival time'):
    27	        chunk.append(end_template)
    28	        for chunk_line in chunk:
    29	            print chunk_line
    30	        chunk = []
    31	        inside_block = 0
    32	    elif inside_block:
    33	        line = line.replace('\n', '')
    34	        tokens = line.split()
    35	        # 1-1) If a letter in 5th column is "r", this would be replaced with "v".
    36	        # If a letter in 5th column is "f", this would be replaced with "^".
    37	        if tokens[4] == 'r':
    38	            tokens[4] = 'v'
    39	        elif tokens[4] == 'f':
    40	            tokens[4] = '^'
    41	
    42	        # 1) replace 5th column with 2nd column. (Swap 2nd and 5th columns.)
    43	        temp = tokens[1]
    44	        tokens[1] = tokens[4]
    45	        tokens[4] = temp
    46	
    47	        # 2) insert two double quotation marks in 1st column. 
    48	        # 3) replace 3rd column with ;
    49	        # 4) replace 4th column with // 
    50	        tokens[0] = '"' + tokens[0] + '"'
    51	        tokens[2] = ';'
    52	        tokens[3] = '//'
    53	
    54	        # Append the transformed stringt to array "chunk"
    55	        transformed_str = ' '
    56	        for item in tokens:
    57	            transformed_str += ' ' + item
    58	        chunk.append(transformed_str)
    59	
$ 
$ python process_input.py input.txt
$path {
  // from: in11
  // to: out432
  $name "test_1" ;
  $cycle 1 ;
  $slack -0.130978 ;
  $transition {
  "in11" v ; // (in)
  "Ckt432/A[7]" v ; // (TopLevel432b)
  "Ckt432/M1/A[7]" v ; // (PriorityA)
  "Ckt432/M1/U7/Y" ^ ; // (INVX1_RVT)
  "Ckt432/M5/U12/Y" v ; // (OA21X1_RVT)
  "Ckt432/M5/Chan[3]" v ; // (DecodeChan)
  "Ckt432/Chan[3]" v ; // (TopLevel432b)
  "out421" v ; // (out)
  }
}

$path {
  // from: in11
  // to: out432
  $name "test_2" ;
  $cycle 1 ;
  $slack -0.130978 ;
  $transition {
  "in37" v ; // (in)
  "Ckt432/A[5]" v ; // (TopLevel432b)
  "Ckt432/M1/A[5]" v ; // (PriorityA)
  "Ckt432/M1/U8/Y" ^ ; // (INVX1_RVT)
  "Ckt432/M1/U13/Y" v ; // (NAND2X0_RVT)
  "Ckt432/M5/U12/Y" v ; // (OA21X1_RVT)
  "Ckt432/M5/Chan[3]" v ; // (DecodeChan)
  "Ckt432/Chan[3]" v ; // (TopLevel432b)
  "out421" v ; // (out)
  }
}

$ 
$ 

Thank you for all your help. RudiC's code works for me. Happy new year!

Best,

Jaeyoung