Як замінити один char на інший у всіх іменах поточних каталогів?


41

Як перейменувати всі файли / підкаталоги в поточній папці?

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

File 1
File 2
File 3
Dir 1
Dir 3

має бути перейменовано на

File_1
File_2
File_3
Dir_1
Dir_3

Відповіді:


36

Якщо вам також потрібно перейменовувати файли у підкаталогах, а ваш findпідтримує -execdirпредикат, тоді ви можете це зробити

find /search/path -depth -name '* *' \
    -execdir bash -c 'mv -- "$1" "${1// /_}"' bash {} \;

Дякую @glenn jackman, що він запропонував -depthваріант findі змусив мене подумати.

Зауважте, що в деяких системах (включаючи GNU / Linux) findможуть не знайти файли, ім'я яких містить пробіли, а також послідовності байтів, які не утворюють дійсних символів (як правило, для медіафайлів з іменами з символами не ASCII, закодованими в наборі відрізняється від локальної). Встановлення локального значення C(як в LC_ALL=C find...) дозволить вирішити проблему.


Вам потрібно було find -maxdepth 1б виконати саме те, що ОП запитало про роботу в поточній папці.
Калеб

1
Скористайтеся -depthопцією find , і ви можете позбутися цього sort.
glenn jackman

@glenn jackman: дякую, я зараз розумію, що моє рішення було неправильним.
enzotib

2
Перехід -name '* *'до -name '*_*'та перейти "${1// /_}"на"${1//_/.}"
enzotib

1
@kroiz: його називають "Заміна шаблону". Ви можете знайти його на bashсторінці man.
enzotib

34

У будь-якій оболонці ви можете перебирати файли, ім'я яких містить пробіл. Замінити пробіли на підкреслення легко в bash, ksh та zsh за допомогою ${VARIABLE//PATTERN/REPLACEMENT}конструкції.

for x in *" "*; do
  mv -- "$x" "${x// /_}"
done

У Debian, Ubuntu та похідних ви можете використовувати Perl rename(інші дистрибутиви подають іншу програму як rename, і ця програма тут не корисна).

rename 's/ /_/g' *

Обов’язкове рішення zsh:

autoload zmv
zmv '(*)' '${1// /_}'

Обов’язкове рішення POSIX:

for x in *" "*; do
  y=$(printf %sa "$x" | tr " " "_")
  mv -- "$x" "${y%a}"
done

Що означає "g" в кінці команди "перейменувати"? Я не бачив цього в посібнику.
JulianLai

Як перейменувати лише каталог? Я не хочу змінювати ім’я файлу.
JulianLai

@JulianLai s/…/…/gозначає замінити всі події. Це не дуже добре пояснено в посібнику . Якщо ви хочете перейменувати каталоги, є способи, будь ласка, знайдіть його (я думаю, я це бачив і раніше), і якщо ви не можете його знайти, задайте нове запитання.
Жил "ТАК - перестань бути злим"

чудово ... це допомогло мені перейменувати всіх _MG_blah.JPGна IMG_blah.JPG.
Абінаш Даш

13

Ви можете використовувати renameдля цього (якщо припустити той util-linux, а не той perl):

cd /path/to/dir
rename ' ' _ *\ *

Це знайде для всіх файлів та каталогів простір в імені та замінить пробіл підкресленням. Оскільки він використовує глобальний збіг файлів, для початку вам потрібно бути у правильному каталозі.

Якщо ви хочете робити рекурсивні збіги, ви можете, але вам, можливо, доведеться виконати renameпару разів, щоб зловити будь-які елементи в каталогах, які самі перейменовані:

cd /path/to/dir
shopt -s globstar
rename ' ' _ **/*\ *
!!; !!

2
" renameПерейменуватимуть вказані файли, замінивши перше входження з їхнього імені на на ". Отже, це буде працювати лише для файлів з одним пробілом у їх імені. (Ви можете зателефонувати renameв циклі, але це насправді не правильний інструмент.)
Жил "SO- перестань бути злим"


1

У Debian / Ubuntu, спираючись на відповіді Калеба і Жиля, саме це працювало для мене, щоб перейменовувати файли рекурсивно:

cd /path/to/dir
shopt -s globstar
rename 's/ /_/g' **

Примітка. Щоб переглянути, які файли будуть перейменовані та як, використовуйте -nперемикач за допомогою rename:

rename -n 's/ /_/g' **

Ще одна примітка: налаштування globstarстворює **файли відповідності у всіх підкаталогах, тому, якщо бажано лише поточний каталог, не встановлюйте globstar або використовуйте *замість нього **.

Ще одна примітка: renameКоманду потрібно запускати не один раз для файлів з кількома зустрічами пошукового терміну.


Це працює лише в тому випадку, якщо каталоги не містять пробілів. (Перейменовані , a b/c dщоб a_b/c_dпрацювати не буде, вам потрібно спочатку перейменувати a b/c dв a b/c_d, а потім a bв a_b).
Стефан Шазелас

@Stephane: Це означає запускати одну і ту ж renameкоманду двічі?
Маркус Пшейдт

Ну, як ніколи стільки разів, скільки є вкладені рівні каталогів з пробілами. В ідеалі потрібно спершу пройти глибину каталогу та перетворити лише базове ім'я файлу, як у прийнятому рішенні. Також зауважте, що bash's **виключає точкові файли та переходи символів.
Стефан Шазелас

0

Якщо ви не флеш в регулярних виразах (я ні!), І ви можете запускати програми, розроблені для kde (або ви використовуєте робочий стіл kde - k, або у вас встановлені бібліотеки), то krename - це чудова графічна утиліта, яка дозволяє вам бачити раніше і після того, як ви почнете зміни. Він має ряд простих перетворень як опцій, а також підтримує регулярні вирази. Ви навіть можете об'єднати кілька послідовних перетворень в одне перейменування, щоб не потрібно було розробити єдине складне перетворення, яке робить це все одночасно. Він також має можливість продовжити перейменування тих самих файлів після того, як буде застосовано перейменування.

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

http://www.krename.net/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.