Как отсортировать буквенно-цифровые строки в Bash - PullRequest
0 голосов
/ 16 октября 2018

Я хочу отсортировать список файлов по имени файла.

Ввод

280900_b24.txt
280900_b23.txt
280900_b25.txt
280900_b28.txt
280900.txt
280900_b27.txt
280900_b22.txt
280900_b30.txt
280900_b29.txt
280902.txt
280902_b01.txt
280901_b08.txt
280901.txt
280900_b26.txt

Ожидаемый вывод

280902_b01.txt
280902.txt
280901_b08.txt
280901.txt
280900_b30.txt
280900_b29.txt
280900_b28.txt
280900_b27.txt
280900_b26.txt
280900_b25.txt
280900_b24.txt
280900_b23.txt
280900_b22.txt
280900.txt

Самое близкое, что я могу получить, это sort -r

280902.txt
280902_b01.txt
280901.txt
280901_b08.txt
280900.txt
280900_b30.txt
280900_b29.txt
280900_b28.txt
280900_b27.txt
280900_b26.txt
280900_b25.txt
280900_b24.txt
280900_b23.txt
280900_b22.txt

, но я хочу файлы с_b # предшествовать файлам без _b # в имени.пример: я хочу, чтобы 280902_b01.txt предшествовал 280902.txt.

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

Похоже, вам нужна обратная сортировка по первой, числовой части.и _ сортировать то же самое и прямую (не обратную) сортировку всего после этого.Это делает то, что вы говорите, что хотите, когда я пытаюсь сделать это с вашими данными:

sort -k1.1,1.6r -k1.8,1.14 input.txt

Это выполняет обратную сортировку по столбцам 1-6, игнорирует столбец 7 и прямую сортировку по столбцам 8–14.

0 голосов
/ 17 октября 2018

Вы можете сделать:

$ echo "280900_b24.txt
280900_b23.txt
280900_b25.txt
280900_b28.txt
280900.txt
280900_b27.txt
280900_b22.txt
280900_b30.txt
280900_b29.txt
280902.txt
280902_b01.txt
280901_b08.txt
280901.txt
280900_b26.txt" | sort -t _ -k1r
280902_b01.txt
280902.txt
280901_b08.txt
280901.txt
280900_b30.txt
280900_b29.txt
280900_b28.txt
280900_b27.txt
280900_b26.txt
280900_b25.txt
280900_b24.txt
280900_b23.txt
280900_b22.txt
280900.txt

Объяснение:

sort -t _ -k1rn
      ^                 split
        ^               on the underscore
           ^            sort on field 1 in reverse order
                        the r is applied to the rest of the fields as well
                        after the first
               ^        numeric for the first field, 'ascii' for the rest

Чтобы показать, что -r относится к остальным полям, рассмотрим:

$ echo {9..11}_{9..11}.txt | tr ' ' '\n' 
9_9.txt
9_10.txt
9_11.txt
10_9.txt
10_10.txt
10_11.txt
11_9.txt
11_10.txt
11_11.txt

Если вы сортируете это таким же образом:

$ echo {9..11}_{9..11}.txt | tr ' ' '\n' | sort -t _ -k1rn
11_10.txt
11_11.txt
11_9.txt
10_10.txt
10_11.txt
10_9.txt
9_10.txt
9_11.txt
9_9.txt

Остальные поля считаются асибетическими.Если вы хотите числовые значения в остальных полях:

$ echo {9..11}_{9..11}.txt | tr ' ' '\n' | sort -t _ -k1rn -k2rn
11_11.txt
11_10.txt
11_9.txt
10_11.txt
10_10.txt
10_9.txt
9_11.txt
9_10.txt
9_9.txt
0 голосов
/ 16 октября 2018

Я не могу проверить это, но я верю, что вы можете сделать

 sort -k1.1,1.6r -k1.8,1.8 -k1.9r

Это, однако, создаст проблемы с

 280900.txt
 280900_b30.txt
 280900_s30.txt

Так что, возможно, лучше сделать

 sort -k1.1,1.6r -k1.7,1.7 -k1.8r

Последний лучше, поскольку он выполняет обратную сортировку по первым 6 символам, а затем обычную сортировку по 7-му символу в случае столкновения в первом.Это решает проблему подчеркивания.Наконец, мы выполняем обратную сортировку остатка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...