Eu tenho uma string simples que renomeará todos os arquivos JPEG em uma pasta sequencialmente:
ls -v | cat -n | while read n f; do mv -n "$f" "pic-$n.jpg"; done
Mas tenho uma pasta com muitos tipos de arquivos diferentes. Existe uma string ou variável simples que eu possa substituir .jpg
para manter as extensões dos arquivos? Ou precisa ser um script completo agora? Eu gostaria de mantê-lo em uma única linha, se possível.
Exemplos
Digamos que eu tenha uma pasta como esta:
a long hash name.mp4
another name.m4v
video.mov
another name.mp4
e assim por diante. Quero renomear os arquivos da seguinte forma para que pareçam mais organizados e não tenham muitos caracteres, assim:
vid-1.mp4
vid-2.m4v
vid-3.mov
vid-4.mp4
Se eu usasse ls -v | cat -n | while read n f; do mv -n "$f" "vid-$n"; done
, não teria extensões de arquivo. Quero manter as extensões dos arquivos porque às vezes é mais fácil abri-los.
Estou me perguntando principalmente se existe uma variável global no bash para definir extensões de arquivo
Não use um loop aqui, apenas use
rename
:Se parecer certo, execute novamente sem
-n
renomear.Explicação:
O
rename
comando é um script perl que pode executar código perl para renomear arquivos. Aqui, estamos usando o operador de substituição (s/old/new/
) com algumas opções especiais:/s
faz com que o operador de substituição trate sua entrada como uma única linha, permitindo.
a correspondência de caracteres de nova linha. Precisamos disso para lidar com nomes de arquivos com novas linhas, como fiz no exemplo acima./e
nos permite avaliar o lado direito (s/left/right/
) como uma expressão perl. A expressão"pic-" . ++$a . "$1"
significa "a stringpic-
, depois o valor da variável$a
incrementado em um e o que quer que tenha correspondido entre parênteses no lado esquerdo". No nosso caso, a extensão.Em seguida, a expressão regular usada (
.*(\..+)
) significa "zero ou mais caracteres (.*
) até o último.
(\.
corresponde a um literal.
), depois um ou mais caracteres (.+
). Como o último\..+
está entre parênteses, isso torna disponível o que foi correspondido (a extensão) como$1
no lado direito.Depois de executar o comando acima sem o
-n
, fiquei com:Alternativamente, você pode fazer isso no shell com algo como:
Aqui, percorremos todos os arquivos (e diretórios, se você não quiser renomear os diretórios, tenha cuidado), salvando cada um como
$file
. Então, obtemos a extensão com${file##*.}
. O${variable##pattern}
formato removerá a correspondência mais longapattern
da variável$variable
. Ao usar${file##*.}
removemos tudo até o último.
, deixando apenas a extensão que salvamos como$ext
.A seguir, o
mv
comando irá renomear$file
parapic-
, mais o valor da variável$i
, com a qual inicializamosi=1
, incrementado em um, seguido de a.
e da extensão.Assim como a
rename
solução acima, esta também pode lidar com nomes de arquivos arbitrários:Se você precisar especificamente que os arquivos sejam nomeados aritmeticamente na ordem de classificação da versão (como em
ls -v
), sugiro algo comoou, se você quiser zerar os novos nomes (o que facilita a classificação subsequente), talvez
Remova o
echo
depois de confirmar que os arquivos corretos serão processados na ordem desejada. Se você não se importa com a legibilidade, é claro que pode escrevê-los como "uma linha", se desejar, por exemplo.