And
And

Reputation: 241

Placing columns in new lines while adding information from previous lines

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

Answers (2)

Jotne
Jotne

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

Sundeep
Sundeep

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

Related Questions