Числовая сортировка файлов, включая отрицательные числа

у меня куча файлов:

adenine-N1_B+1,70_A+0,00.pdb
adenine-N1_B+1,70_A-10,00.pdb
adenine-N1_B+1,70_A+10,00.pdb
adenine-N1_B+1,70_A-15,00.pdb
adenine-N1_B+1,70_A+15,00.pdb
adenine-N1_B+1,70_A-20,00.pdb
adenine-N1_B+1,70_A+20,00.pdb
adenine-N1_B+1,70_A-25,00.pdb
adenine-N1_B+1,70_A+25,00.pdb
adenine-N1_B+1,70_A-30,00.pdb
adenine-N1_B+1,70_A+30,00.pdb
adenine-N1_B+1,70_A-5,00.pdb
adenine-N1_B+1,70_A+5,00.pdb

Я хотел бы сортировать численно, чтобы получить следующее:

adenine-N1_B+1,70_A-30,00.pdb
adenine-N1_B+1,70_A-25,00.pdb
adenine-N1_B+1,70_A-20,00.pdb
adenine-N1_B+1,70_A-15,00.pdb
adenine-N1_B+1,70_A-10,00.pdb
adenine-N1_B+1,70_A-5,00.pdb
adenine-N1_B+1,70_A+0,00.pdb
adenine-N1_B+1,70_A+5,00.pdb
adenine-N1_B+1,70_A+10,00.pdb
adenine-N1_B+1,70_A+15,00.pdb
adenine-N1_B+1,70_A+20,00.pdb
adenine-N1_B+1,70_A+25,00.pdb
adenine-N1_B+1,70_A+30,00.pdb

есть ли для этого команда сортировки? До сих пор у меня было следующее:

for i in $(ls *.pdb | sort -V); do echo $i; done
6
задан wanlei
21.03.2023 15:35 Количество просмотров материала 3609
Распечатать страницу

1 ответ

tl; dr

ls *.pdb | sort -k 1.20g

(Да, я знаю этой и более; см ловушки раздел ниже).


сортировка логики

общая числовая сортировка (sort -g) это тот, который вы хотите, но вы должны указать, где начинаются номера.

ваши примеры имеют вид:

adenine-N1_B+1,70_A-15,00.pdb
                   ^ the number starts here: character 20, always

нет пробелов, так простой sort считает все имя файла одним полем. Вам нужна общая числовая сортировка, которая работы из 20-го символа 1-го поля:

sort -k 1.20g

вы можете ввести более сложную логику. Е. Г. если одна из записей была bogonine-X3_B+1,00_A-12,00.pdb, было бы вполне разумно разложить записи следующим образом:

foo_bar_A+00,00.pdb
   ^   ^ field separators
^ first field starts here
        ^ third field starts here
         ^ the number starts here: field 3, character 2

и отсортировать (например) по первому полю, затем по этим числам, вот так:

sort -t '_' -k 1,1 -k 3.2g

(ср. ответ).


Locale

локаль, указанная среда влияет на порядок сортировки. Можно встретить совет установить LC_ALL=C на всякий случай. Это может быть или не быть то, что вы хотите, в зависимости от того, хотите ли вы лечить последнюю запятую (,) в качестве десятичного разделителя или нет (ну, у вас есть ,00 в каждой записи, так что это не проблема, но это не важно в общем).

Если вам нужно изменить язык только для одного конкретного вызова sort, это путь:

LC_ALL=C sort …

подводные камни в различных подходах

это то, что вы пытались:

for i in $(ls *.pdb | sort -V); do echo $i; done

команда слишком сложна, внутренняя часть делает в основном ту же работу:

ls *.pdb | sort -V

разбор вывода ls is не очень хорошая идея, хотя ваши примеры имен файлов вполне безопасны, так что вам это сойдет с рук. Примечание вам не нужно ls at все:

for i in *.pdb; do echo "$i"; done | sort …

проблема с ls *.pdb вы можете ударить argument list too long ошибка (ну, не в вашем примере, но опять же: в общем). Синтаксис for i in *.pdb; … застрахован.

ваши имена примеров кажутся безопасными для использования с echo а (см. общую проблему с echo). Они не содержат специальных символов, поэтому find … -print0 nor sort -z … etc.

0
отвечен Kamil Maciorowski 2023-03-22 23:23

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх