Ответы:
renameИнструмент , который поставляется с Ubuntu довольно жарко такого рода вещи. Вы можете вставлять маленькие выражения Perl, например, так:
rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *
Это просто покажет вам, что он будет делать. Удалите, -nчтобы сделать это упражнение с огнем.
Это в основном работает путем грубого определения переменной и увеличения ее при каждом попадании в файл. Если у вас будет более 10 файлов, я рекомендую использовать некоторые дополнения нулями в sprintf. Следующее хорошо до 999:
rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *
... Но это достаточно легко расширить.
Чтобы улучшить ответ @ Oli , версияrename инструмента 1.600 от Aristotle Pagaltzis фактически имеет встроенный счетчик $N.
Так что все, что вам нужно, это
rename 's/AS.*/AS$N/' *
Установить,
brew install renameили скачать скрипт/usr/local/bin/brewили /usr/bin)renameпозволяет назначить напрямую $_, что идеально подходит для этой проблемы.Хотя аргументы коды мы передаем в Perl renameутилиты часто выполняют согласование и замену (с s/), и это вполне приемлемо , чтобы решить эту проблему , что путь , там на самом деле нет необходимости в том , что в тех случаях , как этот , где вы на самом деле не следственные или повторное использование текста старых имен файлов. renameпозволяет писать практически любой код на Perl, и его не нужно встраивать внутрь s/ /e. Я предлагаю использовать такую команду:
rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *
Или, если вам хочется сбрить несколько персонажей:
rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *
(Это можно сделать еще короче, но не без ущерба для ясности.)
Обе эти команды делают одно и то же. Каждый показывает, какие операции переименования будут предприняты. Как только вы попробуете один, и вы будете довольны результатами, запустите его снова без -nопции. Как написано, это будет производить имена файлов AS01.txt, AS02.txt..., AS10.txt, AS11.txt, и так далее. Вы можете изменять их по мере необходимости, а затем удалять только тогда, -nкогда вам нравится то, что вы видите.
Если вы хотите увеличить ширину до 2, замените их 2на большее число. Например, если по какой-то причине вам нужны такие имена, как AS00000000000001.txt, вы должны заменить %02dна %014d. Если вы вообще не хотите заполнять поля - даже если это приведет к тому, что ваши файлы появятся в нечисловом порядке, если вы перечислите их позже! - тогда вы можете заменить их %02dпросто %d.
Как это работает? Ваша оболочка раскрывается * в список файлов, прежде чем она даже запускает renameкоманду. Список отсортирован лексикографически (т. Е. По алфавиту) в соответствии с текущими настройками локали. renameполучает имена файлов в качестве аргументов командной строки и обрабатывает их в порядке их перечисления. Выражение ++$iоценивается на единицу больше, чем текущее значение переменной $i, а также устанавливает переменную $iв это вновь увеличенное значение. Это значение передается sprintf, который форматирует его и помещает в другой текст. Этот текст присваивается непосредственно специальной переменной $_, которая содержит имя файла. Поскольку renameфайлы процессов в порядке их передачи в качестве аргументов, они соответственно нумеруются.
Оба объявляют и увеличивают переменную счетчика, и оба sprintfпо существу используют одинаковый способ для вставки значения этого счетчика, дополненного слева нулями, в другой текст новых имен файлов. (Информация в обоих ответах о том, как дополнять нулями - и изменять ширину - даже одинаково применима к обоим.) Причина, по которой они так похожи, заключается в том, что метод в этом предыдущем ответе действительно делает именно это 1 , но с дополнительными шагами, которые полезны для многих проблем, но на самом деле не нужны для этой.
Для сравнения, вот как выглядит вторая команда в этом ответе, если она изменена для использования стиля, который я здесь использовал (и для заполнения до ширины 2, как я сделал здесь, вместо 3):
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *
Часть между этой командой s/.+/и /eв ней теперь совпадает с выражением, которое я назначаю $_(т. Е. Код с правой стороны =оператора) в первой команде в этом ответе.
s/ операторе попытка текста соответствия (имена файлов , что ваша оболочка расширяются от *и передаются в качестве аргументов командной строки , когда бежала rename) с регулярным выражением , и заменой преформ. /используется в качестве разделителя для разделения различных частей sвыражения. Первая часть, .+это регулярное выражение; он соответствует любому 1 символу ( .) и делает это один или несколько раз ( +) . Поскольку имена файлов никогда не бывают пустыми - они всегда имеют длину не менее одного символа - это один из способов сопоставить любое 1 имя файла.our $i; sprintf "AS%02d.txt", ++$i. Это создает новое имя файла. Как правило, используется s/для создания текста, который либо (а) заменяет текст, который соответствует только части имени файла, либо (б) основан на сопоставленном тексте каким-либо образом (например, он может использовать специальную переменную, $&которая расширяется до матч). В этом случае, однако, подобранный текст не используется вообще.our $i; sprintf "AS%02d.txt", ++$iбудет использоваться как имя файла, а не как код. Но /eфлаг в конце заставляет этот текст обрабатываться как исходный код Perl и оценивается, и использует полученное при этом значение (в данном случае возвращаемое значение встроенной sprintfфункции Perl ) в качестве нового имени файла.Хотя я думаю, что метод, который я показал здесь, является более ясным и простым подходом к этой проблеме, чем любой метод, который использует s/с /eэтим, хорошо знать этот метод, потому что он хорошо подходит для ряда других проблем переименования файлов, где все или часть оригинальных имен файлов проверяется и / или сохраняется. Я рекомендую этот блог по Оле (который также написал , что ответ ), который включает в себя несколько таких примеров.
1 Технически, это различие в поведении $_ =команд и s/ /eкоманд. В регулярном выражении .+не совсем верно, что .соответствует любому символу, потому что он не соответствует символу новой строки . Вы, вероятно, не должны использовать имена файлов с символами новой строки в них, но вы можете, и иногда файл получает имя таким образом случайно. Если вам это нравится, сопоставьте выходные данные rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'с результатами rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'. Чтобы .сопоставить новую строку, используйте sфлаг, который идет в конце (с e). То есть пиши /seв конце вместо /e.
Предположим, что файлы, которые вы хотите переименовать, находятся в ~/Adir, и это единственные файлы в этой папке, тогда:
n=0
for f in $( ls ~/Adir | sort ) ; do
n=$(( n+1 ))
mv -n "$f" "AS${n}.txt"
done
Этот скрипт будет просматривать каждый файл ~/Adirи переименовывать его, AS1.txt, AS2.txt, ...если файл не существует (перезаписи не будет). Вот почему вы должны убедиться, что это единственные файлы в ~/Adir. sortКоманда только в случае , если вы хотите , чтобы файлы , чтобы сохранить первоначальный заказ.
renameесть prename. Это может быть лучше, но вы можете добавить инструкции по установке, чтобы сделать этот ответ более ценным.