如何在bash中一个接一个地打印列?

时间:2016-09-02 07:59:53

标签: bash awk sed multiple-columns cut

是否有更好的方法可以将两列或更多列打印到一列中,例如

input.file

AAA    111
BBB    222
CCC    333

输出:

AAA
BBB
CCC
111
222
333

我只能想到:

cut -f1 input.file >output.file;cut -f2 input.file >>output.file

但是,如果有很多列,或者我想将输出传递给其他命令,例如sort,那就不好了。

还有其他建议吗?非常感谢你!

7 个答案:

答案 0 :(得分:6)

使用awk

awk '{if(maxc<NF)maxc=NF;
      for(i=1;i<=NF;i++){(a[i]!=""?a[i]=a[i]RS$i:a[i]=$i)}
      }
     END{
      for(i=1;i<=maxc;i++)print a[i]
     }' input.file

答案 1 :(得分:5)

您可以使用GNU awk array of arrays存储所有数据并在以后打印。

如果列数是常量,则适用于任意数量的列:

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

注意NR代表记录数(即此处的行数),NF代表字段数(即给定行中的字段数)。

如果列数在行上发生变化,那么我们应该使用另一个数组,在这种情况下,存储每行的列数。但是在这个问题上,我没有看到这个请求,所以我暂时离开它。

查看包含三列的示例:

$ 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

如果列数不是常数,使用数组存储每行的列数有助于跟踪它:

$ 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

答案 2 :(得分:2)

awk '{print $1;list[i++]=$2}END{for(j=0;j<i;j++){print list[j];}}' input.file

<强>输出

AAA
BBB
CCC
111
222
333

更简单的解决方案是

 awk -v RS="[[:blank:]\t\n]+" '1' input.file

答案 3 :(得分:1)

将标签视为分隔符:

$ cat <(cut -f 1 asd) <(cut -f 2 asd)
AAA
BBB
CCC
111
222
333

答案 4 :(得分:1)

由于订单不重要:

$ awk 'BEGIN {RS="[ \t\n]+"} 1' file
AAA
111
BBB
222
CCC
333

答案 5 :(得分:0)

这适用于空格分隔的列的任意数量

\src
  |.. A.class
  |.. A.java
  +-- \Package2
      |.. B.class
      |.. B$T.class
   +-- \Package3
      |.. C.Java

如果空格不是单独的......我们假设“:”是分隔符

awk  '{for (A=1;A<=NF;A++) printf("%s\n",$A);}' input.file | sort -u > output.file

答案 6 :(得分:-1)

丑陋,但它有效 -

for i in {1..2} ; do awk -v p="$i" '{print $p}' input.file ; done

{1..2}更改为{1..n},其中'n'是输入文件中的列数

解释 -

我们正在定义一个变量p,它本身就是变量i。我从1到n变化,每一步我们打印文件的第i列。