Мне нужно переименовать ок. 70000 файлов. Например: от sb_606_HBO_DPM_0089000
до sb_606_dpm_0089000
и т. Д.
Диапазон номеров идет от 0089000
до 0163022
. Это только первая часть имени, которая должна измениться. все файлы находятся в одном каталоге и пронумерованы последовательно (последовательность изображений). Числа должны остаться без изменений.
Когда я пытаюсь сделать это в bash, меня смущает, что «список аргументов слишком длинный».
Редактировать:
Сначала я попытался переименовать один файл с помощью mv
:
mv sb_606_HBO_DPM_0089000.dpx sb_606_dpm_0089000.dpx
Затем я попытался переименовать диапазон (на прошлой неделе я узнал, как переместить загрузку файлов, поэтому я подумал, что тот же синтаксис может сработать для переименования файлов ...). Я думаю, что попробовал следующее (или что-то подобное):
mv sb_606_HBO_DPM_0{089000..163023}.dpx sb_606_dpm_0{089000..163023}.dpx
источник
ARG_MAX
пределом оболочки . Поскольку этот вопрос явно требует решения для командной строки, (возможно, равные) решения с графическим интерфейсом, как и в другом вопросе, также не совпадают.mv {1..2} {3..4}
не работает, что является совершенно другой проблемой, чемARG_MAX
... Все остальные, кто ответил, вероятно, будут чувствовать то же самое! Так что, с моей точки зрения, я бы хотел, чтобы вы откатили последнее изменение и, если хотите, задали совершенно новый вопрос об использованииmv
диапазоновargument list too long
ошибке. Больше нет необходимости уточнять, это явно не обман, так как нам нужен обходной путь для работы с ARG_MAX, а ответы в предложенном дубликате этого не делают.Ответы:
Одним из способов является использование
find
с-exec
, и+
вариант. Это создает список аргументов, но разбивает список на столько вызовов, сколько необходимо для работы со всеми файлами без превышения максимального списка аргументов. Это подходит, когда все аргументы будут рассматриваться одинаково. Это в случаеrename
, хотя не сmv
.Вам может понадобиться установить Perl Rename:
Тогда вы можете использовать, например:
Удалить
-n
после тестирования, чтобы фактически переименовать файлы.источник
Я собираюсь предложить три варианта. Каждая из них - простая однострочная команда, но я предоставлю варианты для более сложных случаев, в основном, в случае, если файлы для обработки смешиваются с другими файлами в той же директории.
MMV
Я бы использовал команду mmv из одноименного пакета :
Обратите внимание, что аргументы передаются в виде строк, поэтому расширение оболочки не происходит в оболочке. Команда получает ровно два аргумента, а затем находит соответствующие файлы внутри, без жестких ограничений на количество файлов. Также обратите внимание, что в приведенной выше команде предполагается, что все файлы, соответствующие первому глобу, должны быть переименованы. Конечно, вы можете быть более конкретным:
Если у вас есть файлы за пределами запрошенного диапазона номеров в одном и том же каталоге, вам, возможно, будет лучше, если циклические числа указаны ниже в этом ответе. Однако вы также можете использовать последовательность вызовов mmv с подходящими шаблонами:
зацикливание чисел
Если вы хотите избежать установки чего-либо или вам нужно выбрать по диапазону номеров, избегая совпадений за пределами этого диапазона, и вы готовы ждать 74 023 вызовов команд, вы можете использовать простой цикл bash:
Это работает особенно хорошо здесь, так как в последовательности нет пробелов. В противном случае вы можете проверить, существует ли исходный файл.
Обратите внимание, что в отличие
for ((i=89000; i<=163022; ++i))
от скобки расширение обрабатывает лидирующие нули с момента выпуска Bash пару лет назад. На самом деле изменение, которое я запросил, так что я рад видеть варианты его использования.Дальнейшее чтение: Расширение Brace на информационных страницах Bash, особенно часть о
{x..y[..incr]}
.перебирать файлы
Другой вариант будет заключаться в цикле по подходящему глобу, а не просто в цикле по целому диапазону. Что-то вроде этого:
Опять же, это один
mv
вызов на файл. И снова цикл проходит по длинному списку элементов, но весь список не передается в качестве аргумента подпроцессу, а обрабатывается внутренне с помощью bash, поэтому ограничение не вызовет проблем.Дальнейшее чтение: Расширение параметров оболочки на информационных страницах Bash, документирование
${parameter/pattern/string}
среди прочего.Если вы хотите ограничить диапазон номеров указанным вами, вы можете добавить проверку для этого:
Здесь
${i##pattern}
удаляет самый длинный префикс соответствияpattern
из$i
. Этот самый длинный префикс определяется как что-либо, затем подчеркивание, затем ноль или более нулей. Последний написан как*(0)
расширенный шаблон глобуса, который зависит от устанавливаемойextglob
опции . Удаление начальных нулей важно, чтобы число считалось основанием 10, а не основанием 8.+([0-9])
Аргумент in loop представляет собой еще один расширенный глобус, соответствующий одной или нескольким цифрам, на тот случай, если у вас есть файлы, которые начинаются одинаково, но не заканчиваются на число.источник
Один из способов обойти
ARG_MAX
ограничение - использовать встроенную в bash оболочкуprintf
:Ex.
но
источник
find
в текущем каталоге.
для всех файлов-type f
и переименуйте найденный файл$1
с заменойHBO_DPM
наdmp
один за другим-exec ... \;
заменить
echo
сmv
выполнить переименование.источник
Вы могли бы написать небольшой скрипт на Python, что-то вроде:
Сохраните это как текстовый файл как
rename.py
в папке, в которой находятся файлы, затем с терминалом в этой папке:источник
Вы можете сделать это файл за файлом (это может занять некоторое время) с
Как и Perl,
rename
используемый в других ответах,rename.ul
также имеет опцию-n
или--no-act
для тестирования.источник
-n
флаг, который я использовал для тестирования, и предполагал, что его можно использоватьrename.ul
также.Я вижу, что никто не пригласил моего лучшего друга
sed
на вечеринку :). Следующийfor
цикл достигнет вашей цели:Существует множество инструментов для такой работы, выберите наиболее понятный для вас. Этот простой и легко изменяемый, чтобы соответствовать тем или иным целям ...
источник
$i
в кавычки в подстановке команд, но нелегкий способ обработать завершающий перевод строки в имени файла.Так как мы даем варианты, вот подход Perl.
cd
в целевой каталог и запустите:объяснение
perl -e
: запустить скрипт, указанный-e
.foreach(glob){}
: запустите все, что есть в{ }
каждом результате глобуса.glob("sb_*")
: возвращает список всех файлов и каталогов в текущем каталоге, чьи имена совпадают с глобусом оболочкиsb*
.rename $_, s/_HBO_DPM_/_dpm_/r
: perl magic.$_
это специальная переменная, которая содержит каждый элемент, который мы повторяем (вforeach
). Итак, здесь будет найден каждый файл.s/_HBO_DPM_/_dpm_/
заменяет первое вхождение_HBO_DPM_
с_dpm_
. Он запускается$_
по умолчанию, поэтому он будет запускаться для каждого имени файла. В/r
означает «применить эту замену копию целевой строки (имя файла) и возвращает модифицированную строку.rename
Делает то , что можно было ожидать: он переименовывает файлы Так что все это будет переименовать имя текущего файла (.$_
) К себе с_HBO_DPM_
заменено на_dpm_
.Вы можете написать то же самое, что и расширенный (и более читаемый скрипт):
источник
В зависимости от вида переименования, которое вы планируете, использование vidir с многострочным редактированием может быть удовлетворительным.
В вашем конкретном случае вы можете выделить все строки в текстовом редакторе и удалить часть " HBO" имен файлов за несколько нажатий клавиш.
источник
vidir
?