Renomear vários arquivos com 2 condições / substituições em uma linha?

8

Estou tentando renomear algumas imagens:

IMG_1.JPG
IMG_2.JPG
IMG_3.JPG

Quero substituir IMGpor imge .JPGpor .jpg- eu sei como fazer a segunda parte:

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

Meu problema é que eu não consigo mv IMG_.JPGpara img_.jpg- Eu sei que você pode passar vários padrões para rename, mas eu não consigo usar o nome do arquivo existente com um valor de minúsculas alterada.

Como faço para fazer isso?

treyBake
fonte

Respostas:

10

Talvez você precise usar o comando perl rename. Na minha caixa do CentOS, chama-se '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 [email protected]
$

Se você deseja usar o renamecomando dumb de util-linux(às vezes chamado rename.ul), talvez precise ser executado em duas etapas, por exemplo

$ 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
$
Steve
fonte
3
Note que o perl renameanterior ao idiota renameencontrado no util-linux que você chama de antigo simplesrename . Até é anterior ao Linux.
Stéphane Chazelas
6

Para responder sua pergunta no genérico,

renomear vários arquivos com 2 condições / substituições em uma linha?

você usaria normalmente grupos de captura , referindo-se a eles na expressão de substituição usando suas correspondentes referências anteriores . Por exemplo

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

No entanto, nesse caso em particular, seria mais simples aplicar apenas o modificador em minúsculas \Lao nome inteiro:

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

Outra alternativa, usando mmv

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

(remova o -npara realmente executar a renomeação).

chave de aço
fonte
Ou zmv:zmv '*.JPG' '${(L)f}'
Stéphane Chazelas
1
Uma versão mais simples do rename 's/.*/\L$&/' *.JPGseriarename '$_ = lc' *.JPG
hobbs
2

Usando mv:

sh compatível:

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

bash (Obrigado steeldriver):

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

Isso percorrerá todos os .JPGarquivos no diretório atual e os renomeará com o mesmo nome, com todos os caracteres maiúsculos convertidos em caracteres minúsculos.

jesse_b
fonte
1

A maneira mais simples e baseada na página de manual que não cobre uma expressão regular :

rename 'IMG' 'img' * ; rename 'JPG' 'jpg' *
Hossein Vatani
fonte
IMHO, uma resposta simples como essa alcança o que as batidas pesadas ocasionalmente não conseguem. Nenhuma malícia para programadores experientes, mas como a pergunta parece ser de um novato, a simplicidade precisa ser incentivada.
Hopping Bunny