Как отсортировать файлы численно из командной строки Linux - PullRequest
16 голосов
/ 24 июля 2010

Ладно, сейчас речь идет скорее о Linux, чем о вопросе, но, возможно, кто-то знает, как сделать то, что я хочу.Я знаю, что может быть достигнутым с помощью команды sort, но я хочу лучшего решения, потому что заставить его работать так же просто, как написать программу на C, чтобы сделать то же самое.

У меня есть файлы, для примера, допустим, у меня есть эти файлы: (мои файлы такие же, у меня их много)

  • file-10.xml
  • file-20.xml
  • file-100.xml
  • file-k10.xml
  • file-k20.xml
  • file-k100.xml
  • file-M10.xml
  • file-M20.xml
  • file-M100.xml

Теперь это получаетсяв порядке, в котором я хочу их отсортировать. Кстати, это порядок в Windows , в который они по умолчанию сортируются.Это мило.Windows группирует последовательные числовые символы в один эффективный символ , который сортирует в алфавитном порядке перед буквами.

Если я наберу ls в командной строке linux, я получу следующий мусор.Обратите внимание, что 20 смещен.Это более сложная задача, когда у меня есть сотни таких файлов, которые я хочу просмотреть в отчете, в следующем порядке:

  • file-100.xml
  • file-10.xml
  • file-20.xml
  • file-k100.xml
  • file-k10.xml
  • file-k20.xml
  • file-M100.xml
  • file-M10.xml
  • file-M20.xml

Я могу использовать ls -1 | sort -n -k 1.6, чтобы получить те без 'k' или'M' правильно ...

  • file-k100.xml
  • file-k10.xml
  • file-k20.xml
  • file-M100.xml
  • file-M10.xml
  • file-M20.xml
  • file-10.xml
  • file-20.xml
  • file-100.xml

Я могу использовать ls -1 | sort -n -k 1.7, чтобы ничего не исправить

  • file-100.xml
  • file-10.xml
  • file-20.xml
  • file-k10.xml
  • file-M10.xml
  • file-k20.xml
  • file-M20.xml
  • file-k100.xml
  • file-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

  • file-10.xml
  • file-20.xml
  • file-100.xml
  • file-k10.xml
  • file-k20.xml
  • file-k100.xml
  • file-M10.xml
  • file-M20.xml
  • file-M100.xml

Вот так!Мальчик рад, что "сила командной строки Linux" спасла меня там.(Это не практично для моей ситуации, потому что вместо ls -1 у меня есть команда, которая имеет другую строку или две длинные)

Теперь поведение Windows простое, элегантное и выполняет то, что вы хотитеделать 99% времени.Почему я не могу иметь это в Linux?Почему sort не имеет переключателя "автоматическая сортировка чисел таким образом, который не заставляет меня биться головой в стену"?

Вот псевдокод для C ++:

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;
}

Это было так сложно?Может кто-нибудь поставить это в сортировку и отправить мне копию?Пожалуйста

Ответы [ 3 ]

37 голосов
/ 28 июня 2012

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 как тысячи и миллионы, если это была ваша цель - это просто алфавитный порядок.

16 голосов
/ 24 июля 2010

ls -1v приблизит вас.Он просто сортирует все заглавные буквы перед строчными.

2 голосов
/ 24 июля 2010

Это была бы моя первая мысль:

ls -1 | sed 's/\-\([kM]\)\?\([0-9]\{2\}\)\./-\10\2./' | sort | sed 's/0\([0-9]\{2\}\)/\1/'

Обычно я просто использую sed, чтобы заполнить число нулями, а затем снова использую его для удаления начального нуля.

Я не знаю, может ли это быть быстрее в Perl.

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