Відповіді:
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це ім'я. Це може бути краще, але ви можете додати інструкції з установки, щоб зробити цю відповідь більш цінною.