Bash and Linux

Transpose the rows and columns of a file

mediumawk and cut

Problem statement

A report tool produces space-separated rows, but the dashboard import expects each column as a row. Transpose the file: the first output line is the first column, the second output line is the second column, and so on. Every row has the same number of columns, separated by a single space.

file.txt

TEXT
name age
alice 21
ryan 30

Examples

Example 1

Input: Run the command on `file.txt`.

Output: name alice ryan age 21 30

Hints

Approach

One pass with awk. For every line, the loop walks fields 1 to NF and appends field i to row[i]. On the first line (NR == 1) the entry is initialised with the field alone so there is no leading space; after that, a space and the field are appended. In END, the array holds one finished string per original column, and printing them in index order gives the transposed file. The whole file is read once, and memory grows with the file size.

Bash
awk '{ for (i = 1; i <= NF; i++) row[i] = (NR == 1 ? $i : row[i] " " $i) } END { for (i = 1; i <= NF; i++) print row[i] }' file.txt

Follow-up questions

  • How would you handle a CSV file with , as the separator?
  • What if rows have different numbers of columns?

Frequently asked questions

The awk version already copes, because awk's default separator treats any run of blanks as one. The cut version breaks, since cut -d' ' treats every single space as a separator and returns empty fields. Normalise first with tr -s ' ' if you must use cut.