[英]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.