Ответы:
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. Это может быть лучше, но вы можете добавить инструкции по установке, чтобы сделать этот ответ более ценным.