Как сортировать файлы численно из командной строки linux
Хорошо, теперь это больше о Linux, чем о вопросе, но, возможно, кто-то знает, как делать то, что я хочу. Я знаю, что это может быть достигнуто с помощью команды sort
, но я хочу лучшее решение, потому что получить это для работы так же просто, как написать программу на C, чтобы сделать то же самое.
У меня есть файлы, для аргументов, скажем, у меня есть эти файлы: (мои файлы одинаковы, у меня их гораздо больше)
- файл-10.xml
- файл-20.xml
- файл-100.xml
- файл-k10.xml
- файл-k20.xml
- файл-k100.xml
- файл-M10.xml
- файл-M20.xml
- файл-M100.xml
Теперь это оказывается заказ, который я хочу, чтобы они отсортировались. Кстати, это порядок в Windows, который по умолчанию сортируется. Это хорошо. Windows группирует последовательные числовые символы в один эффективный символ, который сортируется по алфавиту перед буквами.
Если я набираю ls
в командной строке linux, я получаю следующий мусор. Обратите внимание, что 20 перемещается. Это большая сделка, когда у меня есть сотни этих файлов, которые я хочу просмотреть в отчете, по порядку.
- файл-100.xml
- файл-10.xml
- файл-20.xml
- файл-k100.xml
- файл-k10.xml
- файл-k20.xml
- файл-M100.xml
- файл-M10.xml
- файл-M20.xml
Я могу использовать ls -1 | sort -n -k 1.6
, чтобы получить те, у которых нет "k" или "M" правильно...
- файл-k100.xml
- файл-k10.xml
- файл-k20.xml
- файл-M100.xml
- файл-M10.xml
- файл-M20.xml
- файл-10.xml
- файл-20.xml
- файл-100.xml
Я могу использовать ls -1 | sort -n -k 1.7
, чтобы получить правильное значение
- файл-100.xml
- файл-10.xml
- файл-20.xml
- файл-k10.xml
- файл-M10.xml
- файл-k20.xml
- файл-M20.xml
- файл-k100.xml
- файл-M100.xml
Хорошо, отлично. Пусть все будет правильно. ls -1 | grep "file-[0-9]*\.xml" | sort -n -k1.6 && ls -1 file-k*.xml | sort -n -k1.7 && ls -1 file-M*.xml | sort -n -k1.7
- файл-10.xml
- файл-20.xml
- файл-100.xml
- файл-k10.xml
- файл-k20.xml
- файл-k100.xml
- файл-M10.xml
- файл-M20.xml
- файл-M100.xml
Уф! Мальчик рад, что "сила командной строки Linux" спасла меня там. (Это не практично для моей ситуации, потому что вместо ls -1
у меня есть команда, которая является другой строкой или двумя длинными)
Теперь поведение Windows простое, элегантное и делает то, что вы хотите, чтобы он выполнял 99% времени. Почему я не могу это использовать в Linux? Почему oh почему sort
не имеет "автоматных номеров сортировки таким образом, чтобы я не переводил меня в стену"?
Здесь псевдокод для С++:
bool compare_two_strings_to_avoid_head_injury(string a, string b)
{
string::iterator ai = a.begin();
string::iterator bi = b.begin();
for(; ai != a.end() && bi != b.end(); ai++, bi++)
{
if (*ai is numerical)
gobble up the number incrementing ai past numerical chars;
if (*bi is numerical)
gobble up the number incrementing bi past numerical chars;
actually compare *ai and *bi and/or the gobbled up number(s) here
to determine if we need to compare more chars or can return the
answer now;
}
return something here;
}
Было ли так сложно? Может кто-то поместить это в сортировку и отправить мне копию? Пожалуйста?
Ответы
Ответ 1
Это была бы моя первая мысль:
ls -1 | sed 's/\-\([kM]\)\?\([0-9]\{2\}\)\./-\10\2./' | sort | sed 's/0\([0-9]\{2\}\)/\1/'
В основном, я просто использую sed
для заполнения числа нулями, а затем снова использую его, чтобы отменить начальный нуль.
Я не знаю, может ли быть быстрее в Perl.
Ответ 2
Try sort --version-sort -f
- file-10.xml
- file-20.xml
- file-100.xml
- file-k10.xml
- файл-k20.xml
- file-k100.xml
- file-M10.xml
- file-M20.xml
- файл-M100.xml
Параметр -f должен игнорировать регистр (в противном случае он помещает k и M в неправильный порядок в этом примере). Тем не менее, я не думаю, что сортировка неправильно интерпретирует буквы k и M как тысячи и миллионы, если это была ваша цель - ее просто алфавитный порядок.
Ответ 3
ls -1v
доставит вас довольно близко. Он просто сортирует все заглавные буквы перед нижним регистром.