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!
source to share
$ 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.
source to share