各フィールドを数字でソートし、フィールド数を区切ります。

各フィールドを数字でソートし、フィールド数を区切ります。

を使用していくつかのデータをソートしようとしています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ソート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オプションがない場合、ソート時に行全体が考慮されます。

以下についてもっと読むことができます。情報コアユーティリティの並べ替えページ。

答え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

関連情報