Reputation: 241
I want to reduce the number of columns in my file to 3, by placing all columns beyond column #3 into new lines and have those strings preceded by the column #1 and #2 values from the previous line. This is a bit abstract so here is an example:
Column1 Column2 Column3
A1 B1 C1
A2 B2 C2 D2
A3 B3 C3 D3 E3
A4 B4 C4
turn into
Column1 Column2 Column3
A1 B1 C1
A2 B2 C2
A2 B2 D2
A3 B3 C3
A3 B3 D3
A3 B3 E3
A4 B4 C4
Each Cn
, Dn
, and En
value needs the information of An
and Bn
.
I found the solution to the first part of my problem here: https://www.unix.com/shell-programming-and-scripting/125202-awk-new-line-between-columns.html
awk '{print $1,$2,$3"\n"$4"\n"$5}' oldfile > newfile
this yields
Column1 Column2 Column3
A1 B1 C1
A2 B2 C2
D2
A3 B3 C3
D3
E3
A4 B4 C4
So An
and Bn
are missing for the moved strings. Unfortunately a bunch of empty new lines is generated as well, they can either be rid of in an extra step, or in the same process, I don't care about that.
Upvotes: 1
Views: 81
Reputation: 41456
A version that do not use loop, but not flexible if number of column increases.
awk '{s=$1FS$2;print s,$3 ($4?"\n"s FS$4:"") ($5?"\n"s FS$5:"")}' file
Column1 Column2 Column3
A1 B1 C1
A2 B2 C2
A2 B2 D2
A3 B3 C3
A3 B3 D3
A3 B3 E3
A4 B4 C4
Upvotes: 1
Reputation: 23667
Use a loop:
$ awk '{for(i=3;i<=NF;i++) print $1, $2, $i}' ip.txt
Column1 Column2 Column3
A1 B1 C1
A2 B2 C2
A2 B2 D2
A3 B3 C3
A3 B3 D3
A3 B3 E3
A4 B4 C4
for(i=3;i<=NF;i++)
the variable i
will start from 3
and loop until NF
(number of fields)print $1, $2, $i
always print first and second fields and then the field based on variable i
Upvotes: 2