使用bash水平sorting数据
我有一个文件充满了列中的数据
sarah mark john 10 20 5 xyz
我想sorting的数据,所以列保持不变,但第二行是在增加的顺序,所以它看起来像这样:
john sarah mark 5 10 20 zxy
我一直在看sorting命令,但只能find垂直sorting,而不是水平。 我很高兴使用任何工具,任何帮助表示赞赏。 谢谢!
让我们创build一个函数来转置一个文件(使行成为列,列变成行):
transpose () { awk '{for (i=1; i<=NF; i++) a[i,NR]=$i; max=(max<NF?NF:max)} END {for (i=1; i<=max; i++) {for (j=1; j<=NR; j++) printf "%s%s", a[i,j], (j<NR?OFS:ORS) } }' }
这只是将所有数据加载到一个二维数组a[line,column]
,然后将其作为a[column,line]
打印回来,以便转换给定的input。 wrapper transpose () { }
被用来存储它作为一个bash函数。 你只需要复制粘贴到你的shell(或者在~/.bashrc
如果你希望它是一个永久的函数,可以在任何时候打开一个会话)。
然后,通过使用它,我们可以很容易地解决这个问题,通过使用sort -n -k2
:基于列2的数字sorting。然后,转置回来。
$ cat a | transpose | sort -n -k2 | transpose john sarah mark 5 10 20 zxy
如果你想有一个很好的格式作为最终的输出,只需pipe道到这样的column
:
$ cat a | transpose | sort -n -k2 | transpose | column -t john sarah mark 5 10 20 zxy
一步步:
$ cat a | transpose sarah 10 x mark 20 y john 5 z $ cat a | transpose | sort -n -k2 john 5 z sarah 10 x mark 20 y $ cat a | transpose | sort -n -k2 | transpose john sarah mark 5 10 20 zxy
来自一个重复的问题 ,这将sorting第一行的列:
#!/bin/bash input="$1" order=$((for i in $(head -1 $input); do echo $i; done) | nl | sort -k2 | cut -f1) grep ^ $input | (while read line do read -a columns <<< "${line%"${line##*[![:space:]]}"}" orderedline=() for i in ${order[@]} do orderedline+=("${columns[$i - 1]}") done line=$(printf "\t%s" "${orderedline[@]}") echo ${line:1} done)
要按第二行sorting,请将head -1 $input
replacehead -1 $input
head -2 $input | tail -1
head -2 $input | tail -1
。 如果sorting应该是数字,请将sort -n -k2
而不是sort -k2
。
良好的一行可以完成工作:
perl -ane '$,=" "; print sort @F; print "\n";' file
我在这里find它: http : //www.unix.com/unix-for-advanced-and-expert-users/36039-horizontal-sorting-lines-file-sed-implementation.html