Відповіді:
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' *
... Але це досить просто для розширення.
Для того, щоб поліпшити @ Оля відповіді , то rename
інструмент версія 1,600 від Аристотеля 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 символу ( .
) , і робить це один або кілька разів ( +
) . Оскільки імена файлів ніколи не порожньо - they're завжди принаймні один символ довго - це один з способів , щоб відповідати будь-який 1 файлу.our $i; sprintf "AS%02d.txt", ++$i
. Це створює нове ім'я файлу. Як правило, використовується s/
для створення тексту, який або (а) замінює текст, який збігається лише з частиною імені файлу, або (b) на основі відповідного тексту певним чином (наприклад, він може використовувати спеціальну змінну, $&
яка розширюється на матч). Однак у цьому випадку відповідний текст взагалі не використовується.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
це ім'я. Це може бути краще, але ви можете додати інструкції з установки, щоб зробити цю відповідь більш цінною.