194. Transpose File
Given file.txt:
1name age
2alice 21
3ryan 30
Desired Output:
1name alice ryan
2age 21 30
Solution
1cat file.txt | awk '{
2 for (i = 1; i <= NF; i++) {
3 if (NR == 1) {
4 cols[i] = $i
5 } else {
6 cols[i] = cols[i] " " $i
7 }
8 }
9}
10END {
11 for (i = 1; i <= length(cols); i++) {
12 print cols[i]
13 }
14}'
Transposing a File with awk
Transposing a file means converting rows into columns and columns into rows. This is useful in various data manipulation tasks.
awk Basics
NF(Number of Fields): The number of fields in the current line (record). (column)NR(Number of Records): The line number or the number of records read so far. Incremented automatically with each new line. (row)
awk Script for Transposing Explanation
1{
2 for (i = 1; i <= NF; i++) {
3 if (NR == 1) {
4 cols[i] = $i
5 } else {
6 cols[i] = cols[i] " " $i
7 }
8 }
9}
- The
{}block is executed for each record (line) read from the input.
Loop Through Fields
1for (i = 1; i <= NF; i++) {
NF(Number of Fields): Number of fields in the current record.- Loops through each field from
1toNF.
First Record Handling
1if (NR == 1) {
2 cols[i] = $i
3}
NR(Number of Records): The current record number.- For the first record, initialise the
colsarray with fields from the first line.
Subsequent Records
1else {
2 cols[i] = cols[i] " " $i
3}
- For subsequent lines, append the current field
$ito the existing string incols[i], separated by a space.
Handling the End of Input
1END {
2 for (i = 1; i <= length(cols); i++) {
3 print cols[i]
4 }
5}
- The
ENDblock executes after all lines have been processed. - Prints each column (now a row in the transposed format).
Example Workflow
Given file.txt:
1name age
2alice 21
3ryan 30
Processing Each Record
First Record (NR == 1)
NFis 2 (two fields:nameandage).- The loop runs from
i = 1toi = 2.
1cols[1] = "name"
2cols[2] = "age"
Second Record (NR == 2)
NFis 2 (two fields:aliceand21).- The loop runs from
i = 1toi = 2.
1cols[1] = "name alice"
2cols[2] = "age 21"
Third Record (NR == 3)
NFis 2 (two fields:ryanand30).- The loop runs from
i = 1toi = 2.
1cols[1] = "name alice ryan"
2cols[2] = "age 21 30"
Final Output
1name alice ryan
2age 21 30
Debugging the awk Script
You can add print statements inside your awk script to debug and see what’s happening at each step.
Debugging Script
1cat file.txt | awk '{
2 print "Processing line:", NR
3 for (i = 1; i <= NF; i++) {
4 if (NR == 1) {
5 cols[i] = $i
6 } else {
7 cols[i] = cols[i] " " $i
8 }
9 print "cols[" i "] =", cols[i]
10 }
11}
12END {
13 print "\n[RESULT]"
14 for (i = 1; i <= length(cols); i++) {
15 print cols[i]
16 }
17}'
Output with Debugging Statements
1Processing line: 1
2cols[1] = name
3cols[2] = age
4Processing line: 2
5cols[1] = name alice
6cols[2] = age 21
7Processing line: 3
8cols[1] = name alice ryan
9cols[2] = age 21 30
10
11[RESULT]
12name alice ryan
13age 21 30