How to print columns one after the other in bash?

后端 未结 7 1380
感情败类
感情败类 2021-01-14 19:06

Is there any better methods to print two or more columns into one column, for example

input.file

AAA    111
BBB    222
CCC    333

o

7条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-14 19:18

    You can use a GNU awk array of arrays to store all the data and print it later on.

    If the number of columns is constant, this works for any amount of columns:

    gawk '{for (i=1; i<=NF; i++)            # loop over columns
               data[i][NR]=$i               # store in data[column][line]
          }
          END {for (i=1;i<=NR;i++)          # loop over lines
                    for (j=1;j<=NF;j++)     # loop over columns
                         print data[i][j]   # print the given field
          }' file
    

    Note NR stands for number of records (that is, number of lines here) and NF stands for number of fields (that is, the number of fields in a given line).

    If the number of columns changes over rows, then we should use yet another array, in this case to store the number of columns for each row. But in the question I don't see a request for this, so I am leaving it for now.

    See a sample with three columns:

    $ cat a
    AAA    111  123
    BBB    222  234
    CCC    333  345
    $ gawk '{for (i=1; i<=NF; i++) data[i][NR]=$i} END {for (i=1;i<=NR;i++) for (j=1;j<=NF;j++) print data[i][j]}' a
    AAA
    BBB
    CCC
    111
    222
    333
    123
    234
    345
    

    If the number of columns is not constant, using an array to store the number of columns for each row helps to keep track of it:

    $ cat sc.wk 
    {for (i=1; i<=NF; i++)
           data[i][NR]=$i
     columns[NR]=NF
    }
    END {for (i=1;i<=NR;i++)
                for (j=1;j<=NF;j++)
                     print (i<=columns[j] ? data[i][j] : "-")
    }
    $ cat a
    AAA    111  123
    BBB    222
    CCC    333  345
    $ awk -f sc.wk a
    AAA
    BBB
    CCC
    111
    222
    333
    123
    -
    345
    

提交回复
热议问题