Як я можу використовувати перейменувати, щоб рекурсивно перейменувати кожне у великі регістри


11

Я хотів би рекурсивно перейменувати всі файли та папки (підпапки) у великі регістри.

Я знайшов кілька сценаріїв, які будуть робити це з малого регістру, але я не знаю, як їх змінити, так що це буде робити навпаки (нижній до верхнього).

Сценарій, який я знайшов і працює для малих літер, але я не знав, як змінити:

rename 'y/A-Z/a-z/' *

Це від man rename.


Не знаючи нічого про команду перейменування, я підозрюю, що якщо ви спробуєте, rename 'y/a-z/A-Z/' *ви отримаєте те, що хочете. Обережно, де ви це протестуєте.
Уорвік

це не рекурсивно (бо початковий не був ...), але це працює. Я не можу зрозуміти, чому я не торкнувся цього виступу :), тоді!
jnhghy - Олександру Джантеа

Я думаю, що, враховуючи якість відповіді Жилла, було б добре, якщо ти приймеш його відповідь, віддаючи перевагу моїй. Він набагато повніший, ніж мій, і пояснює ваші варіанти (і як це все працює). Дякую.
Warwick

Відповіді:


8

Зауважте, що ви використовуєте скрипт Perl, який називаєтьсяrename розподіленим Debian та похідними (Ubuntu, Mint, ...). Інші дистрибутиви Linux постачають зовсім іншу і значно менш корисну команду rename.

y/A-Z/a-z/переводить кожен символ в діапазоні Aчерез Zу відповідний символ в діапазоні aчерез z, тобто ASCII прописних літер у відповідній малої літери. Щоб виконати зворотний переклад, використовуйте y/a-z/A-Z/. Інший спосіб написати ту ж команду , яка rename '$_ = uc($_)' *ucце у PPER з функцією ази, а renameкоманда перейменовує файли , заснована на перетворенні з до $_змінному.

rename '…' *лише перейменовує файли в поточному каталозі, тому що це *відповідає. Файли з крапками (файли, ім'я яких починається з .) теж пропускаються.

Якщо ви хочете перейменувати файли в поточному каталозі та в підкаталогах рекурсивно, ви можете скористатися findкомандою для рекурсивного перегляду поточного каталогу. Тут є складнощі: якщо ви телефонуєте rename, це перейменовує і каталог, і частину базового імені. Якщо ви закликаєте renameдо каталогу, перш ніж повторити його ( find -exec rename … {} \;), findзаплутаєтесь, оскільки знайдений каталог, але цей каталог вже не існує до моменту, коли він намагається спуститися до нього. Ви можете подолати це, сказавши findпройти каталог перед тим, як діяти на нього, але потім ви намагаєтесь перейменувати foo/barйого, FOO/BARале каталог FOOне існує.

Простий спосіб уникнути цієї складності - змусити команду перейменування діяти лише на базовій частині імені шляху. Регулярний вираз ([^/]*\Z)відповідає кінцевій частині шляху, яка не містить /.

find . -depth -exec rename 's!([^/]*\Z)!uc($1)!e' {} +

Оболонка zsh надає більш зручні функції для перейменування - навіть більш виразні, ніж Perl, але складніше і часто простіше складати.

Функція zmvперейменовує файли на основі шаблонів. Запустіть autoload -U zmvодин раз, щоб активувати його (покладіть цей рядок у своє .zshrc).

У першому аргументі zmv(шаблон, який потрібно замінити) ви можете використовувати потужні шаблони підстановки zsh . У другому аргументі zmv(текст заміни) ви можете використовувати його функції розширення параметрів , включаючи модифікатори історії .

zmv -w '**/*' '$1$2:u'

Пояснення:

  • -w - автоматичне призначення числових змінних кожному шаблону підстановки
  • **/*- всі файли в підкаталогах, рекурсивно ( **/відповідає 0, 1 або більше рівнів підкаталогів)
  • $1 - перша числова змінна, яка відповідає каталозі частини кожного шляху
  • $2:u- друга числова змінна, яка відповідає базовій частині імені кожного шляху, з :uмодифікатором для перетворення значення у верхній регістр

Як додатковий бонус, це враховує параметри місцевого оточення.

Якщо ви не впевнені в zmvнаписаній вами команді, ви можете пропустити -nопцію надрукувати те, що виконувала б команда, і нічого не змінити. Перевірте висновок, і якщо він виконує те, що ви хочете, повторіть команду без -nфактичного дії.


5

Викрадений (з незначною редакцією) з публікації Gilles тут

find <DIR> -depth -type d -exec rename -n 's!/([^/]*/?)$!\U/$1!' {} +


Це не діє рекурсивно.
Жил "ТАК - перестань бути злим"

Правда. Я повинен був правильно прочитати питання. У мене немає доступу до команди перейменування, але я вважаю, що це буде працювати рекурсивно -find <dir> -exec rename 'y/a-z/A-Z/' {} \;
Warwick

Це трохи складніше, ніж це, тому що ви перейменовуєте каталоги, а findв них повторюєтесь.
Жил 'ТАК - перестань бути злим'

@Gilles - Гаразд. Провівши трохи досліджень, виявляється, що мені потрібно додати параметр -depth, щоб знайти, щоб імена каталогів оброблялися останніми. Таким чином, find <dir> -depth -exec rename 'y/a-z/A-Z/' {} \;слід вирішити питання щодо перейменування каталогів. Правильно?
Уорвік

Ні, це все ще не працює, тому що renameзміни , наприклад , foo/barдо FOO/BARі FOOне існує в цій точці.
Жил 'SO- перестань бути злим'

2

Я хотів би направити будь-кого, хто все ще пов'язаний з цією відповіддю на відмінну відповідь, яку на це запитання дав Гієльс Керно, який не потребує find.

Отримана команда буде:

shopt -s globstar
rename -n 'y/a-z/A-Z/' **

Але перед запуском, будь ласка, прочитайте відповідь, пов’язану із застереженнями щодо старих версій bash.

Нарешті на випадок, коли хтось цікавиться, що робить y///команда perl regex. Ось посилання на відповідну документацію .


1

find -execdir| перейменувати

Це був би найкращий спосіб зробити це, якби не відносне безумство шляху, оскільки це дозволяє уникнути Perge regex fu діяти лише на базове ім'я:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find a -depth -execdir rename 's/(.*)/\U$1/' '{}' \;

-execdirПерший cds в каталог перед виконанням лише базового імені.

На жаль, я не можу позбутися цієї PATHхакерської частини, find -execdirвідмовляється робити що-небудь, якщо у вас є відносний шлях у PATH...: /ubuntu/621132/why-using-the-execdir-action- це-небезпечно для каталогу, яке-є-в-шляху / 1109378 # 1109378


0

Спробуйте це після переходу до каталогу, де ви хочете перейменувати файли:

for word in `ls -ltr |tail -n +2 |awk '{print $9}'`
do
  a=$(echo $word | tr '[a-z]' '[A-Z]')
  mv $word $a
  echo "Done Successfully"
done

Не розбирайте висновок ls (а чому б на Землі ви працювали ls -lлише для того, щоб відрізати стовпці, окрім назви?), І використовуйте подвійні лапки навколо змінних підстановок . Ваш код надмірно складний і розбивається на імена файлів, що містять пробіли та інші спеціальні символи. Використання findабо **/повторне використання в підкаталогах, вихід lsлише для споживання людиною.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.