Как сортировать файлы численно из командной строки 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 доставит вас довольно близко. Он просто сортирует все заглавные буквы перед нижним регистром.