Найти и отсортировать числовые имена файлов

344
hadi k

Я пытаюсь найти файлы, которые соответствуют, time=*а затем нужно отобразить его, отсортировав его численно.
Имена файлов результатов будут такими:

first/path/time=001.jpg first/path/time=002.jpg second/path/time=001.jpg ... 

который я хочу видеть как,

first/path/time=001.jpg second/path/time=001.jpg first/path/time=002.jpg ... 

отсортировано по количеству по 3 цифрам в имени файла.

Сейчас я попробовал find . -name time=* | rev | sort | rev

который работает для однозначных цифр, но с номерами, как 019 021это не работает.

Полный путь будет что-то вроде

path/to/folder1/alpha=0.1_beta=0.2_gamma=1.0/time=001.jpg path/to/folder1/alpha=0.1_beta=0.2_gamma=0.1/time=001.jpg path/to/folder2/alpha=0.1_beta=0.2_gamma=0.1/time=001.jpg . . . 

Я думаю, что было бы проще, если бы файлы могли быть отсортированы, используя только последние 7 символов. 001.jpg 010.jpg... однако, к сожалению sort, не поддерживает отрицательную индексацию для получения последних 6 символов :(

2
(1) Какая ОС? Похоже, какой-то Unix, все же вы должны сделать это ясно. (2) Цитировать шаблон, [или еще] (https://superuser.com/q/1217773/432690) ... Kamil Maciorowski 6 лет назад 1
Эй, это Linux, и что вы подразумеваете под цитатой? hadi k 6 лет назад 0
Я имею в виду именно то, что говорит мой ответ под [этой ссылкой, которую я уже дал вам] (https://superuser.com/q/1217773/432690). Kamil Maciorowski 6 лет назад 0
привет спасибо, но это не было проблемой со мной. У меня нет файла `time = *` в текущем каталоге, чтобы иметь эту проблему. Но определенно новая вещь, чтобы учиться! еще раз спасибо! Я буду держать это в поисках на будущее. hadi k 6 лет назад 0
@KamilMaciorowski о нет. я просто имел ввиду `time = 001.jpg`` time = 002.jpg` и так далее. hadi k 6 лет назад 0

3 ответа на вопрос

2
Tomasz

Это должно сделать:

find . -name 'time=*' | sort -t= -k3 

Но это более безопасная сортировка, согласно комментарию Камиля Мачоровского:

perl -C -F= -wnle 'push @a,[$_,split(/\./,$F[-1])]; END {$,="\n"; print map{$$_[0]} sort{$$a[1]<=>$$b[1]} @a}' 

Используйте его в конвейере, findа не sortв первом.

Если только вы не встретите `третий / путь / a = foo / bar / ...`. Kamil Maciorowski 6 лет назад 0
@KamilMaciorowski `Я пытаюсь найти файлы, которые соответствуют времени = *` говорит вопрос. Tomasz 6 лет назад 0
Добавьте `third / path / a = foo / bar / time = 001.jpg` к набору, предоставленному OP. Это закончится после `first / path / time = 002.jpg` из-за дополнительного` = `. Ваш ответ может или не может быть достаточным для ОП, полезно знать его ограничения. Может быть, другой ответ также ошибочен; Я не знаю достаточно `ruby`, чтобы сказать. Kamil Maciorowski 6 лет назад 1
Привет @tomasz, спасибо за ваш ответ, но, как говорит @Kamil, он на самом деле не работает для меня, так как мой фактический путь похож на `first / path / parameter = 1 / time = 001.jpg`` first / path / parameter = 0.1 / time = 001.jpg` `секунда / путь / параметр = 1 / time = 001.jpg` ... :( hadi k 6 лет назад 0
@KamilMaciorowski Хороший вопрос, спасибо. Tomasz 6 лет назад 0
@hadik Если это регулярно и как вы представляете, измените `-k2` на` -k3`. Tomasz 6 лет назад 0
@tomasz классное решение, это действительно сработало. хорошая комбинация -t и -k, у меня есть обычные имена, так что это отлично, спасибо! :) hadi k 6 лет назад 0
Ха, не знал, что вариант `sort`. +1 mvw 6 лет назад 0
@hadik Добро пожаловать. Я добавил Perl для странных случаев. Tomasz 6 лет назад 0
2
Kamil Maciorowski

Предполагая, что никакой путь не является достаточно безумным, чтобы потребовать find ... -print0:

find . -type f -name "time=*" | awk -F '=' '{ print $NF "=" $0 }' | sort -n | cut -d "=" -f 2- 

Я использовал awkдля извлечения частей за последним =, он выводит полные строки с дополнительной соответствующей частью впереди, разделяя на дополнительные = . Например:

001.jpg=path/to/folder1/alpha=0.1_beta=0.2_gamma=1.0/time=001.jpg 

Они отсортированы по номерам sort. Затем cutизвлекает части после этого дополнительного (первого) =; это оригинальные пути.

Есть ровно четыре процесса создания: find, awk, sort, cut. Альтернативы, которые используют синтаксис find ... -exec some_tool ... \;создания одного some_toolпроцесса на соответствующий файл.

я не знал о `awk`, спасибо за предложения :) hadi k 6 лет назад 0
1
mvw

Quickie с остатками я выбрал из командной строки :-)

find . -name time="*" -exec ruby -e "s='{}'; puts s.split('=')[-1].split('.')[0]+s" \; | sort -n | colrm 1 3 

Объяснение:

Мой друг Ruby хранит строку пути, заданную командой find as, {}и сохраняет ее в переменной s. Затем она разбивает строку по =символам и сохраняет последнюю часть (индекс -1 в массиве результатов), например 002.jpg. Затем она разбивает эту строку на .символы и сохраняет первую часть (индекс 0 в массиве результатов), предполагая, что файлы имеют имена ddd.<ext>, что приводит к трехзначному числу, например 002.

Наконец она печатает это и добавляет исходную строку пути. Это дало бы:

002./alpha=0.1_beta=0.2_gamma=1.0/path/time=002.jpg 001./alpha=0.1_beta=0.2_gamma=1.0/path/time=001.jpg 021./alpha=0.1_beta=0.2_gamma=0.1/path/time=021.jpg 001./alpha=0.1_beta=0.2_gamma=0.1/path/time=001.jpg 019./alpha=0.1_beta=0.2_gamma=0.1/path/time=019.jpg 

Дополнительные команды конвейера сортируют выходные данные численно ( sort -n) и, наконец, удаляют первые три столбца выходных данных ( colrm 1 3).

Пример:

test$ find . -name time="*" -exec ruby -e "s='{}'; puts s.split('=')[-1].split('.')[0]+s" \;  | sort -n | colrm 1 3 ./alpha=0.1_beta=0.2_gamma=0.1/path/time=001.jpg ./alpha=0.1_beta=0.2_gamma=1.0/path/time=001.jpg ./alpha=0.1_beta=0.2_gamma=1.0/path/time=002.jpg ./alpha=0.1_beta=0.2_gamma=0.1/path/time=019.jpg ./alpha=0.1_beta=0.2_gamma=0.1/path/time=021.jpg 
эта проблема та же, что и у другого решения, предложенного @tomasz. так как мой путь содержит несколько `=`, это сортирует числа после первого `=`, а затем второго `=` и так далее. Так что мои файлы на самом деле не отсортированы, как мне нравится. hadi k 6 лет назад 0
ОК, могу ли я взять последний "="? (Обратите внимание, что я обновил индекс с «1» до «-1») mvw 6 лет назад 0
@hadik Обратите внимание, что вы добавили это требование о множественном "=" после того, как я опубликовал свою первую версию. mvw 6 лет назад 0
Похоже, что Ruby вызывается для каждого найденного файла. Tomasz 6 лет назад 0
Да, это был быстрый взлом. Это не оптимизировано. mvw 6 лет назад 0
@mvw спасибо за ответ. это работает сейчас, но решение Томаш было проще для моей проблемы :) hadi k 6 лет назад 0
По крайней мере, у меня был `f1rst p0st` :-) mvw 6 лет назад 1

Похожие вопросы