Переименовать несколько файлов с двумя условиями / заменами в одну строку?

8

Я пытаюсь переименовать несколько изображений:

IMG_1.JPG
IMG_2.JPG
IMG_3.JPG

Я хочу заменить IMGна imgи .JPGс .jpg- я знаю, как сделать вторую часть:

$ rename 's/\.JPG$/\.jpg/' *.JPG

Моя проблема в том, что я не могу это mv IMG_.JPGсделать img_.jpg- я знаю, что вы можете передавать несколько шаблонов rename, но я не могу использовать существующее имя файла с измененным значением в нижнем регистре.

Как мне это сделать?

treyBake
источник

Ответы:

10

Возможно, вам нужно использовать команду perl rename. На моей коробке CentOS это называется «prename».

$ ls
IMG_1.JPG  IMG_2.JPG  IMG_3.JPG
$ prename 's/^IMG/img/;s/\.JPG$/\.jpg/' *JPG
$ ls
img_1.jpg  img_2.jpg  img_3.jpg
$

$ prename -h
Usage: prename [OPTION]... PERLEXPR FILE...
Rename FILE(s) using PERLEXPR on each filename.

  -b, --backup                  make backup before removal
  -B, --prefix=SUFFIX           set backup filename prefix
  -f, --force                   remove existing destinations, never prompt
  -i, --interactive             prompt before overwrite
  -l, --link-only               link file instead of reame
  -n, --just-print, --dry-run   don't rename, implies --verbose
  -v, --verbose                 explain what is being done
  -V, --version-control=METHOD  override the usual version control
  -Y, --basename-prefix=PREFIX  set backup filename basename prefix
  -z, -S, --suffix=SUFFIX       set backup filename suffix
      --help                    display this help and exit
      --version                 output version information and exit

The backup suffix is ~, unless set with SIMPLE_BACKUP_SUFFIX.  The
version control may be set with VERSION_CONTROL, values are:

  numbered, t     make numbered backups
  existing, nil   numbered if numbered backups exist, simple otherwise
  simple, never   always make simple backups

Report bugs to pederst@cpan.org
$

Если вы хотите использовать команду dumb renameиз util-linux(иногда вызываемой rename.ul), возможно, нужно выполнить ее в два этапа, например

$ ls
IMG_1.JPG  IMG_2.JPG  IMG_3.JPG
$ rename IMG img *JPG
$ rename JPG jpg *JPG
$ ls
img_1.jpg  img_2.jpg  img_3.jpg
$
Стив
источник
3
Обратите внимание, что perl renameпредшествующий тупой renameнайден в util-linux, который вы называете просто старыйrename . Это даже предшествует Linux.
Стефан Шазелас
6

Чтобы ответить на ваш вопрос в общем,

переименовать несколько файлов с двумя условиями / заменами в одну строку?

вы обычно используете группы захвата , ссылаясь на них в выражении замены, используя их соответствующие обратные ссылки . Например

$ rename -n 's/^(.*)_(.*)\.JPG$/\L$1_$2.jpg/' *.JPG
rename(IMG_2.JPG, img_2.jpg)
rename(IMG_3.JPG, img_3.jpg)

Однако в этом конкретном случае было бы проще просто применить модификатор в нижнем регистре \Lко всему имени:

$ rename -n 's/.*/\L$&/' *.JPG
rename(IMG_2.JPG, img_2.jpg)
rename(IMG_3.JPG, img_3.jpg)

Еще одна альтернатива, используя mmv

$ mmv -n '*.JPG' '#l1.jpg'
IMG_2.JPG -> img_2.jpg
IMG_3.JPG -> img_3.jpg

(удалите, -nчтобы фактически выполнить переименование).

steeldriver
источник
Или zmv«S:zmv '*.JPG' '${(L)f}'
Stéphane Chazelas
1
Более простая версия rename 's/.*/\L$&/' *.JPGбыла быrename '$_ = lc' *.JPG
Хоббс
2

Использование mv:

ш совместим:

for file in *.JPG; do mv "$file" "$(echo "$file" | tr '[:upper:]' '[:lower:]')"; done

Баш (спасибо Steeldriver):

for file in *.JPG; do mv "$file" "${file,,}"; done

Это зацикливает все .JPGфайлы в текущем каталоге и переименовывает их в одно и то же имя, причем все заглавные буквы преобразуются в строчные.

jesse_b
источник
1

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

rename 'IMG' 'img' * ; rename 'JPG' 'jpg' *
Хоссейн Ватани
источник
ИМХО, простой ответ, подобный этому, дает то, чего иногда не удается при сильном ударе. Никакой злости по отношению к опытным программистам, но поскольку вопрос, кажется, от новичка, простота должна поощряться.
Прыгающий кролик