简体   繁体   English

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

[英]How to print columns one after the other in bash?

Is there any better methods to print two or more columns into one column, for example 例如,是否有更好的方法可以将两列或更多列打印到一列中

input.file 输入文件

AAA    111
BBB    222
CCC    333

output: 输出:

AAA
BBB
CCC
111
222
333

I can only think of: 我只能想到:

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

But it's not good if there are many columns, or when I want to pipe the output to other commands like sort . 但是,如果有很多列,或者我想将输出传递给其他命令(例如sort ,那就不好了。

Any other suggestions? 还有其他建议吗? Thank you very much! 非常感谢你!

With awk 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

You can use a GNU awk array of arrays to store all the data and print it later on. 您可以使用GNU awk 数组阵列来存储所有数据并在以后打印它。

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). 注意NR表示记录数(即此处的行数), NF表示字段数(即给定行中的字段数)。

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
awk '{print $1;list[i++]=$2}END{for(j=0;j<i;j++){print list[j];}}' input.file

Output 产量

AAA
BBB
CCC
111
222
333

More simple solution would be 更简单的解决方案是

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

Expects tab as delimiter: 选项卡作为分隔符:

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

Since the order is of no importance: 由于订单不重要:

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

This will work for an arbitrary number fo space separated colums 这适用于空格分隔的任意数量的柱子

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

If space is not the separateor ... let's suppose ":" is the separator 如果空间不是独立的......让我们假设“:”是分隔符

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

Ugly, but it works- 丑陋,但它有效 -

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

Change the {1..2} to {1..n} where 'n' is the number of columns in the input file {1..2}更改为{1..n} ,其中'n'是输入文件中的列数

Explanation- 说明-

We're defining a variable p which itself is the variable i. 我们定义一个变量p,它本身就是变量i。 i varies from 1 to n and at each step we print the 'i'th column of the file. 我从1到n变化,在每一步我们打印文件的第i列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM