сортировать каждое поле по номерам, изменяя количество полей

сортировать каждое поле по номерам, изменяя количество полей

Я пытаюсь отсортировать некоторые данные с помощью 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': значение ASCII для '2' равно 50, значение ASCII для '8' равно 56, а для 'b' равно 98.

При числовой сортировке ( sort -n) нечисловые записи сортируются обычным методом, но интерпретируются как ноль по сравнению с числами, например, 23 или 8; но поскольку значение рассматривается как число, а не символьное значение, '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

Связанный контент