我有一个文件,其内容如下所示:
19.58 1925 Alpha
20.40 1924 Otter
13.66 1920 Gold
我试图“按列”对其进行排序以输出以下内容:
13.40 1920 Alpha
19.58 1924 Gold
20.66 1925 Otter
我尝试过各种代码组合,例如:
cat files | sort -t. -k1,1n | sort -t " " -k2,2n -k3,3r k4,4n
但这不会输出想要的结果。我怎样才能实现我提到的排序?
答案1
printf "%s.%s %s %s\n" $(paste <(awk -F'[. ]' '{print $1}' file | sort -n) <(awk -F'[. ]' '{print $2}' file | sort -n) <(awk -F'[. ]' '{print $3}' file | sort -n) <(awk -F'[. ]' '{print $4}' file | sort))
输出:
1920 年 13.40 阿尔法 19.58 1924 黄金 20.66 1925 水獭
答案2
如果你有 GNU awk
,那么可以通过特殊数组的一点帮助来完成排序PROCINFO
:
awk -F '[. ]' '{for(i=1;i<NF+1;i++) a[i][NR]=$i} \
END{PROCINFO["sorted_in"]="@val_num_asc"; \
for(j=1;j<NF+1;j++){ I=0; for(i in a[j]) A[++I][j]=a[j][i]} \
for(i=1;i<NR+1;i++){ printf A[i][1]"."; \
for(j=2;j<NF+1;j++) printf A[i][j]" "; printf "\n"}}' file
上面的代码乍一看可能很复杂,但实际上非常简单 - 它只是将整个文件存储在 array 中a
,最后根据A
需要将其诉诸 array 。主要技巧是@val_num_asc
当我们想要按数字升序对列进行排序时使用。
它应该适用于任意数量的行和列,只需记住整个文件存储在内存中,因此对于大型表来说可能会很慢。
答案3
#!/bin/sh
for i in 1 2 3 4
do
tr . " " < "${1:?}" | cut -d' ' -f$i | sort > $$-$i
done
paste -d. $$-[12] | paste -d' ' - $$-[34]
rm $$-[1234]