フィールド数を可変にして、すべてのフィールドを数値順に並べ替える

フィールド数を可変にして、すべてのフィールドを数値順に並べ替える

を使ってデータをソートしようとしていますsort。数値ではなく桁でソートされている-nことに気づいたので、フラグを追加しました。しかし、最初のフィールドでは数値でソートするだけのように見えます。行のフィールド数が異なるため、フィールドごとに分類するのは問題です (そして、率直に言って、その動作は理解できません)。以下は、私が試していた、ほぼ近いサンプル データです。

echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n18 2\nb 10\n18 15\nb a 2\n23 9\nb 2" | sort -n

Input     Want      Expect?   sort      -n        -n -k1,1 -k2,2 -k3,3 -k4,4…

b b 1     8 2       a 1       23 44     a 1       b a 1
23 44     8 15      a 7       23 9      a 7       b a 10
b 3       23 9      b a 1     8 15      b 1       b a 2
a 7       23 44     b a 2     8 2       b 10      b b 1
b b 2     a 1       b a 10    a 1       b 2       b b 10
a 1       a 7       b b 1     a 7       b 3       b b 2
b a 10    b 1       b b 2     b 1       b a 1     a 1
b b 10    b 2       b b 10    b 10      b a 10    b 1
b 1       b 3       b 1       b 2       b a 2     b 2
b a 1     b 10      b 2       b 3       b b 1     b 3
8 2       b a 1     b 3       b a 1     b b 10    a 7
b 10      b a 2     b 10      b a 10    b b 2     b 10
8 15      b a 10    8 2       b a 2     8 15      8 2
b a 2     b b 1     8 15      b b 1     8 2       8 15
23 9      b b 2     23 9      b b 10    23 44     23 9
b 2       b b 10    23 44     b b 2     23 9      23 44

理想的には、GNU coreutils sort 5.93 を搭載したそのマシンで動作させたいと思っています。単純な Unix ツールで処理したいのです。問題を Perl などに任せたくはありません。[架空の] に相当するものを望んでいます。sort --numeric-sort --all-fields --actually-work

答え1

問題は、何をしているのか理解していないことだと思いますsort。基本的なソートは ASCII 文字値に基づいており、数字は大文字の前にあり、大文字は小文字の前にあります: '1' == 49、'A' == 65、'a' = 97。これは、sort'23' などの数字が '8 ' の前にソートされ、'b b' の前にある列を説明しています: '2' の ASCII 値は 50、'8' の ASCII 値は 56、'b' の ASCII 値は 98 です。

数値でソートする場合 ( sort -n)、数値以外のエントリは通常の方法でソートされますが、23 や 8 などの数値と比較すると 0 として解釈されます。ただし、値は文字値ではなく数値として扱われるため、「8」は「23」の前にあります。したがって、アルファベットのエントリは数値のエントリの前にソートされます。

最善の方法は、各列が同じタイプの値(すべて数字またはすべて英数字)を持つようにデータを正規化し、適切に並べ替えることです。

最後の列 (フィールドによるソート) では、4 つ (またはそれ以上) のフィールドを明示的に指定しているため、フィールド数の多いエントリが最初にソートされます。つまり、(1,2,3) が (1,2) の前になります。この-kオプションがない場合、ソートは行全体を考慮します。

詳細は以下をご覧ください。情報 coreutils ソートページ。

答え2

echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n18 2\nb 10\n18 15\nb a 2\n23 9\nb 2" \
| sed -r 's/[a-z]/9999&/g' | sort -n -k1 -k2 -k3 | sed 's/9999//g' 
18 2
18 15
23 9
23 44
a 1
b 1
b 2
b 3
a 7
b 10
b a 1
b b 1
b a 2
b b 2
b a 10
b b 10

これがあなたが望むものでしょうか? 数値の場合は数値順に並べ替え、数値を他の文字より前にしますか?

ソートによって文字列を最後に配置するため、すべての文字列の前に大きな数字を付け、最後に大きな数字 (9999) を削除します。

答え3

数年にわたる開発の成果により、sort -Vまさにsort 8.26望んでいた出力が生成されます。

$ echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n8 2\nb 10\n8 15\nb a 2\n23 9\nb 2" \
   | sort -V
8 2
8 15
23 9
23 44
a 1
a 7
b 1
b 2
b 3
b 10
b a 1
b a 2
b a 10
b b 1
b b 2
b b 10

関連情報