我有多列数据,我希望重新格式化,使每一列在一个列中彼此“重叠”。
输入示例:
1 2 3 4
1 2 3 4
期望的输出:(修复了缺少“1”和“3”的旧拼写错误)
1
1
2
2
3
3
4
4
(有时我也想在列之间添加空格)
编辑: 关于“之间的空格”的评论不清楚。有时我想要在堆叠的列之间有一个空行。改编下面埃德·莫顿接受的答案,这可以通过以下方式实现
awk '
{for (i=1; i<=NF; i++) a[i]=a[i] $i ORS}
END {for (i=1; i<=NF; i++) printf "%s", a[i](i==NF?"":"\n")}
' file
答案1
用于datamash
转置数据,然后tr
将空格转换为换行符(同时-s
将多个空格压缩为一个)。
datamash -t' ' transpose <infile | tr -s ' ' '\n'
答案2
这可能就是您想要的,在每个 Unix 机器上的任何 shell 中使用任何 awk:
$ awk '
{ for (i=1; i<=NF; i++) a[i] = a[i] $i ORS }
END { for (i=1; i<=NF; i++) printf "%s", a[i] }
' file
1
1
2
2
3
3
4
4
答案3
GNU grep 怎么样:
grep -o '\S*' infile
或者,扩展(相当于)\S
:
grep -o '[^ \t\r\n\v\f]*' infile
如果需要保留列的顺序,请尝试(使用GNU排序)
$ awk '{for (i=1;i<=NF;i++){ print i,$i }}' infile |
sort -snbk 1,1 |
awk '{$1=""}1'
1
1
2
2
3
3
4
4
或者,仅使用awk
, 以及类似于转置列的过程:
awk '{ for(i=1;i<=NF;i++) { f[i]=(f[i]==""?"":f[i] ORS) $i; if(NF>n) n=NF}}
END { for(i=1; i<=n; i++) { print f[i] } }
' infile
答案4
这个答案依赖于切换打印列和行的顺序,实际上生成原始数据的转置。
OP 的问题中更新了相同的输出,正如预期的那样,它最初是不正确的。
for i in `seq 4`; do
awk -v field=$i '{ print $field }' infile;
done
1
1
2
2
3
3
4
4