Я должен переименовать приблизительно 70 000 файлов. Например: От sb_606_HBO_DPM_0089000
кому: sb_606_dpm_0089000
и т.д.
Диапазон числа идет от 0089000
кому: 0163022
. Это - только первая часть имени, которое должно измениться. все файлы находятся в единственном каталоге и пронумерованы последовательно (последовательность изображений). Числа должны остаться неизменными.
Когда я пробую это в ударе, он сереет во мне, что 'Список аргументов является слишком длинным'.
Править:
Я сначала пытался переименовать единственный файл с 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
Один путь состоит в том, чтобы использовать find
с -exec
, и +
опция. Это создает список аргументов, но повреждает список в как много вызовов по мере необходимости для работы на все файлы, не превышая список аргумента maximum. Это подходит, когда все аргументы будут рассматривать то же. Дело обстоит так с rename
, хотя не с mv
.
Вы, возможно, должны установить Perl, переименуйте:
sudo apt install rename
Затем можно использовать, например:
find . -maxdepth 1 -exec rename -n 's/_HBO_DPM_/_dpm_/' {} +
Удалить -n
после тестирования, для фактического переименования файлов.
Я собираюсь предложить три альтернативы. Каждый - простая однострочная команда, но я обеспечу варианты для более сложных случаев, главным образом в случае, если файлы для обработки смешаны с другими файлами в том же directrory.
Я использовал бы команду mmv от пакета того же имени:
mmv '*HBO_DPM*' '#1dpm#2'
Обратите внимание, что аргументы передаются как строки, таким образом, расширения шарика не происходит в оболочке. Команда получает точно два аргумента и затем находит соответствующие файлы внутренне без трудных пределов на количество файлов. Также обратите внимание, что команда выше предполагает, что все файлы, которые соответствуют первому шарику, должны быть переименованы. Конечно, Вы свободны быть более конкретными:
mmv 'sb_606_HBO_DPM_*' 'sb_606_dpm_#1'
Если у Вас есть файлы вне требуемого диапазона числа в том же каталоге, Вы могли бы быть более обеспечены с циклом по числам, данным далее вниз в этом ответе. Однако Вы могли также использовать последовательность mmv вызовов с подходящими шаблонами:
mmv 'sb_606_HBO_DPM_0089*' 'sb_606_dpm_0089#1' # 0089000-0089999
mmv 'sb_606_HBO_DPM_009*' 'sb_606_dpm_009#1' # 0090000-0099999
mmv 'sb_606_HBO_DPM_01[0-5]*' 'sb_606_dpm_01#1#2' # 0100000-0159999
mmv 'sb_606_HBO_DPM_016[0-2]*' 'sb_606_dpm_016#1#2' # 0160000-0162999
mmv 'sb_606_HBO_DPM_01630[01]?' 'sb_606_dpm_01630#1#2' # 0163000-0163019
mmv 'sb_606_HBO_DPM_016302[0-2]' 'sb_606_dpm_016302#1' # 0163020-0163022
Если Вы не хотите устанавливать что-нибудь или должны выбрать диапазоном числа, избегающим соответствий вне этого диапазона, и Вы готовы ожидать 74 023 вызовов команды, Вы могли использовать простой цикл удара:
for i in {0089000..0163022}; do mv sb_606_HBO_DPM_$i sb_606_dpm_$i; done
Это работает особенно хорошо здесь, так как нет никаких разрывов в последовательности. Иначе Вы могли бы хотеть проверить, существует ли исходный файл на самом деле.
for i in {0089000..0163022}; do
test -e sb_606_HBO_DPM_$i && mv sb_606_HBO_DPM_$i sb_606_dpm_$i
done
Отметьте это в отличие от for ((i=89000; i<=163022; ++i))
расширение фигурной скобки действительно обрабатывает начальные нули начиная с некоторого выпуска Bash несколько лет назад. На самом деле изменение, которое я запросил, таким образом, я рад видеть варианты использования для него.
Дальнейшее чтение: Расширение фигурной скобки на страницах информации о Bash, особенно часть о {x..y[..incr]}
.
Другая опция состояла бы в том, чтобы циклично выполниться по подходящему шарику вместо просто цикличного выполнения по целочисленному рассматриваемому диапазону. Что-то вроде этого:
for i in *HBO_DPM*; do mv "$i" "${i/HBO_DPM/dpm}"; done
Снова это - то mv
вызов на файл. И снова цикл по длинному списку элементов, но целый список не передается как аргумент подпроцессу, но обрабатывается внутренне ударом, таким образом, предел не вызовет Вас проблемы.
Дальнейшее чтение: Расширение Параметра Shell на страницах информации о Bash, документируя ${parameter/pattern/string}
среди других.
Если Вы хотели ограничить диапазон числа тем Вы, если, Вы могли добавить проверку на это:
for i in sb_606_HBO_DPM_+([0-9]); do
if [[ "${i##*_*(0)}" -ge 89000 ]] && [[ "${i##*_*(0)}" -le 163022 ]]; then
mv "$i" "${i/HBO_DPM/dpm}"
fi
done
Здесь ${i##pattern}
удаляет самое долгое соответствие префикса pattern
от $i
. Тот самый длинный префикс определяется, поскольку что-либо, затем подчеркивание, затем обнуляет или больше нулей. Последний записан как *(0)
который является расширенным шаблоном шарика, который зависит от extglob
опция установлена. Удаление начальных нулей важно для обработки числа, поскольку основа 10 не базируется 8. +([0-9])
в цикле аргументом является другой расширенный шарик, соответствуя одной или нескольким цифрам, на всякий случай у Вас есть файлы там, которые запускают то же, но не заканчиваются в числе.
Один способ работать вокруг ARG_MAX
предел состоит в том, чтобы использовать встроенную оболочку удара printf
:
printf '%s\0' sb_* | xargs -0 rename -n 's/HBO_DPM/dpm/'
Напр.
rename -n 's/HBO_DPM/dpm/' sb_*
bash: /usr/bin/rename: Argument list too long
но
printf '%s\0' sb_* | xargs -0 rename -n 's/HBO_DPM/dpm/'
rename(sb_606_HBO_DPM_0089000, sb_606_dpm_0089000)
.
.
.
rename(sb_606_HBO_DPM_0163022, sb_606_dpm_0163022)
find . -type f -exec bash -c 'echo $1 ${1/HBO_DPM/dpm}' _ {} \;
./sb_606_HBO_DPM_0089000 ./sb_606_dpm_0089000
find
в текущем каталоге .
для всех файлов -type f
и действительно переименуйте найденный файл $1
с заменой HBO_DPM
с dmp
один за другим -exec ... \;
замена echo
с mv
для выполнения переименовывают.
Можно сделать это файл файлом (это может занять время) с
sudo apt install util-linux # if you don't have it already
for i in *; do rename.ul HBO_DPM dpm "$i"; done
Как Perl rename
используемый в других ответах, rename.ul
имеет также опцию -n
или --no-act
для тестирования.
Вы могли записать немного сценария Python, что-то как:
import os
for file in os.listdir("."):
os.rename(file, file.replace("HBO_DPM", "dpm"))
Сохраните это как текстовый файл как rename.py
в папке файлы находятся в, затем с терминалом в той папке пойдите:
python rename.py
Так как мы даем опции, вот подход Perl. cd
в целевой каталог и выполненный:
perl -e 'foreach(glob("sb_*")){rename $_, s/_HBO_DPM_/_dpm_/r}'
perl -e
: запустите скрипт, данный -e
.foreach(glob){}
: выполните то, что находится в { }
на каждом результате шарика. glob("sb_*")
: возвратите список всех файлов и каталоги в текущем каталоге, имена которого соответствуют шарику оболочки sb*
. rename $_, s/_HBO_DPM_/_dpm_/r
: волшебство жемчуга. $_
специальная переменная, которая содержит каждый элемент, по которому мы выполняем итерации (в foreach
). Таким образом, здесь, это будет каждый найденный файл. s/_HBO_DPM_/_dpm_/
заменяет первое вхождение _HBO_DPM_
с _dpm_
. Это работает $_
по умолчанию, таким образом, это будет работать на каждом имени файла. /r
означает, "применяют эту замену к копии целевой строки (имя файла) и возвращают измененную строку. rename
делает то, что Вы ожидали бы: это переименовывает файлы. Таким образом, все это переименует текущее имя файла ($_
) к себе с _HBO_DPM_
замененный _dpm_
.Вы могли записать то же самое как расширенный (и больше читаемого сценария):
#! /usr/bin/env perl
use strict;
use warnings;
foreach my $fileName (glob("sb_*")){
## Copy the name to a new variable
my $newName = $fileName;
## change the copy. $newName is now the changed version
$newName =~ s/_HBO_DPM_/_dpm_/;
## rename
rename $fileName, $newName;
}
Я вижу, что никто не пригласил моего лучшего друга sed
стороне :). Следующее for
цикл выполнит Вашу цель:
for i in sb_606_HBO_DPM*; do
mv "$i" "$(echo $i | sed 's/HBO_DPM/dpm/')";
done
Существует много инструментов для такого задания, выбирают то, которое является самым понятным для Вас. Этот прост и легок измененный для удовлетворения этому или другим целям...
В зависимости от вида переименования Вы предполагаете, использование vidir с несколькими редактированием строк может быть удовлетворительным.
В Вашем особом случае Вы могли выбрать все строки в своем текстовом редакторе и удалить _ часть "HBO" имен файлов в немногих нажатиях клавиш.