内容は次のようなファイルがあります。
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
上記のコードは一見すると複雑に見えますが、実際には非常に簡単です。ファイル全体を配列に保存し、a
最後にA
必要に応じて配列を使用します。主なトリックは、@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]