Eu tenho muitos arquivos com .abc
extensão e quero alterá-los para .edefg
Como fazer isso na linha de comando?
Eu tenho uma pasta raiz com muitas subpastas, portanto a solução deve funcionar recursivamente.
command-line
bash
rename
batch-rename
tommyk
fonte
fonte
Respostas:
Uma maneira portátil (que funcionará em qualquer sistema compatível com POSIX):
No bash4, você pode usar a globstar para obter globs recursivos (**):
O
rename
comando (perl) no Ubuntu pode renomear arquivos usando a sintaxe de expressão regular perl, que você pode combinar com a globstar oufind
:Veja também http://mywiki.wooledge.org/BashFAQ/030
fonte
"${1%.abc}"
expande para o valor de$1
exceto sem.abc
no final. Veja o faq 100 para mais informações sobre manipulações de string de shell.${1%.abc}...
sh -c
o primeiro argumento é atribuído a $ 0 e os argumentos restantes são atribuídos aos parâmetros posicionais . Portanto,_
é um argumento fictício e '{}' é o primeiro argumento posicional ash -c
.Isso fará a tarefa necessária se todos os arquivos estiverem na mesma pasta
Para renomear os arquivos recursivamente, use isto:
fonte
rename 's/.abc$/.edefg/' /path/to/root/folder/**/*.abc
em uma versão moderna do Bash.s
no começo, e que outras opções posso usar lá. Obrigado !Um problema com as renomeações recursivas é que, independentemente do método usado para localizar os arquivos, ele passa o caminho inteiro para
rename
, não apenas o nome do arquivo. Isso dificulta a renomeação complexa em pastas aninhadas.Eu uso
find
a-execdir
ação de para resolver este problema. Se você usar em-execdir
vez de-exec
, o comando especificado será executado no subdiretório que contém o arquivo correspondente. Então, ao invés de passar o caminho inteirorename
, ele apenas passa./filename
. Isso facilita muito escrever o regex.Em detalhe:
-type f
significa apenas procurar arquivos, não diretórios-name '*.abc'
significa apenas nomes de arquivos de correspondência que terminam em .abc'{}'
é o espaço reservado que marca o local em-execdir
que o caminho encontrado será inserido. As aspas simples são necessárias, para permitir que ele lide com nomes de arquivos com espaços e caracteres de shell.-type
e-name
são o caractere de continuação de linha bash. Eu os uso para tornar este exemplo mais legível, mas eles não são necessários se você colocar seu comando em uma única linha.-execdir
linha é necessária. Ele existe para escapar do ponto-e-vírgula, que encerra o comando executado por-execdir
. Diversão!Explicação do regex:
s/
início da regex\.\/
coincidir com o ./ principal que o -execdir passa. Use \ para escapar do. e / metacaracteres (nota: esta parte varia dependendo da sua versão dofind
. Veja o comentário do usuário @apollo)(.+)
corresponde ao nome do arquivo. Os parênteses capturam a correspondência para uso posterior\.abc
escape do ponto, combine o abc$
ancorar a partida no final da string/
marca o final da parte "correspondente" da regex e o início da parte "substituir"version1_
adicione este texto a cada nome de arquivo$1
referencia o nome do arquivo existente, porque o capturamos entre parênteses. Se você usar vários conjuntos de parênteses na parte "correspondente", poderá consultá-los aqui usando $ 2, $ 3 etc..abc
o novo nome do arquivo terminará em .abc. Não há necessidade de escapar do metacaractere de ponto aqui na seção "substituir"/
fim da regexAntes
Depois de
Dica:
rename
a opção -n é útil. Ele executa uma execução a seco e mostra quais nomes serão alterados, mas não faz nenhuma alteração.fonte
--execdir
não passou na liderança,./
portanto a\.\/
parte no regex pode ser omitida. Pode ser que eu esteja no OSX e não no ubuntuOutra maneira portátil:
fonte
Veja também a entrada sobre por que você não deve analisar
ls
.Editar: se você precisar usar o nome da base, sua sintaxe será:
https://unix.stackexchange.com/questions/19654/changing-extension-to-multiple-files
fonte
Isto é o que eu fiz e funcionou da maneira que eu queria. Eu usei o
mv
comando. Eu tinha vários.3gp
arquivos e queria renomeá-los todos para.mp4
Aqui está um breve guia para ele:
Que simplesmente varre o diretório atual, pega todos os arquivos .3gp e renomeia (usando o mv) para
ren-name_of_file.mp4
fonte
file.3gp
parafile.3gp.mp4
, o que pode não ser o que a maioria das pessoas deseja..3gp
ou.mp4
aqui foram apenas para fins ilustrativos.basename "$i" .mp4
para remover a extensão anterior em vez de "ren- $ i.mp4".Eu encontrei uma maneira fácil de conseguir isso. Para alterar extensões de muitos arquivos de jpg para pdf, use:
fonte
Eu usaria o comando mmv do pacote com o mesmo nome :
Os
;
corresponde a zero ou mais*/
e corresponde#1
na substituição. O*
corresponde a#2
. A versão não recursiva seriafonte
Renomeie arquivos e diretórios com
find -execdir | rename
Se você vai renomear arquivos e diretórios, não apenas com um sufixo, esse é um bom padrão:
A
-execdir
opção impressionante faz umcd
no diretório antes de executar orename
comando, ao contrário-exec
.-depth
verifique se a renomeação ocorre primeiro nos filhos e, depois, nos pais, para evitar possíveis problemas com os diretórios-pai ausentes.-execdir
é necessário porque a renomeação não funciona bem com caminhos de entrada sem nome de base, por exemplo, o seguinte falha:A
PATH
invasão é necessária porque-execdir
tem uma desvantagem muito irritante:find
é extremamente opinativa e se recusa a fazer qualquer coisa-execdir
se você tiver algum caminho relativo em suaPATH
variável de ambiente, por exemplo./node_modules/.bin
, falhando com:Consulte também: Por que o uso da ação '-execdir' é inseguro para o diretório que está no PATH?
-execdir
é uma extensão de localização GNU para POSIX .rename
é baseado em Perl e vem dorename
pacote. Testado no Ubuntu 18.10.Mudar o nome da solução alternativa à procura
Se seus caminhos de entrada não vierem
find
, ou se você já teve o suficiente do aborrecimento do caminho relativo, podemos usar alguns Perl lookahead para renomear com segurança diretórios como em:Eu não encontrei um análogo conveniente para
-execdir
comxargs
: https://superuser.com/questions/893890/xargs-change-working-directory-to-file-path-before-executing/915686O
sort -r
é necessário para garantir que os arquivos vir após seus respectivos diretórios, desde caminhos mais longos vir após mais curtos com o mesmo prefixo.fonte