Complex linear copying and on-the-fly modification with grep or sed

Is there a way to do the following with grep or sed: read each line of the file and copy it twice and modify each copy:

Original line:

X Y Z
A B C

      

New lines:

Y M X
Y M Z
B M A
B M C

      

where X, Y, Z, M are all integers and M is a fixed integer (i.e. 2) that we enter when copying! I believe the solution (if any) will be so difficult that people (myself included) will start bleeding after watching it!

+3


source to share


3 answers


$ awk -v M=2 '{print $2,M,$1; print $2,M,$3;}' file
Y 2 X
Y 2 Z
B 2 A
B 2 C

      

How it works

  • -v M=2

    This defines the variable M

    to have a value of 2.

  • print $2,M,$1

    This prints the second column M

    followed by the first column.

  • print $2,M,$3

    This prints the second column M

    followed by the third column.

extended version

Suppose we want to handle an arbitrary number of columns in which we print all columns between the first and last, then M followed by the first, and then we print all the columns between the first and last, followed by an M followed by the last. In this case, use:

awk -v M=2 '{for (i=2;i<NF;i++)printf "%s ",$i; print M,$1; for (i=2;i<NF;i++)printf "%s ",$i; print M,$NF;}' file

      

Consider this input file as an example:



$ cat file2
X Y1 Y2 Z
A B1 B2 C

      

The above gives:

$ awk -v M=2 '{for (i=2;i<NF;i++)printf "%s ",$i; print M,$1; for (i=2;i<NF;i++)printf "%s ",$i; print M,$NF;}' file2
Y1 Y2 2 X
Y1 Y2 2 Z
B1 B2 2 A
B1 B2 2 C

      

The key change to the code is the addition of the following command:

for (i=2;i<NF;i++)printf "%s "

      

This command prints all columns from i=2

which is the column after the first character i=NF-1

, which is the column before the last. Otherwise, the code is the same.

+3


source


Sure; You can write:



sed 's/\(.*\) \(.*\) \(.*\)/\2 M \1\n\2 M \3/'

      

+2


source


With bash built-in commands:

m=2; while read a b c; do echo "$b $m $a"; echo "$b $m $c"; done < file

      

Output:

Y 2 X
Y 2 Z
B 2 A
B 2 C
+1


source







All Articles