Tenho um diretório que contém arquivos de imagem que devem ser exibidos no bash. Enquanto ecoando, desejo substituir o nome do arquivo e a extensão no comando de linha única.
Arquivos de exemplo:
images/file_name_1.jpg images/file_name_2.jpg
Normalmente, posso fazer uma substituição única como esta:
for i in images/*; do echo ${i/file/image}; done
E a saída fica como:
images/image_name_1.jpg images/image_name_2.jpg
Como posso mantê-lo em loop for e substituir a string “jpg” por “png” também? É apenas uma instância, eu poderia substituir o ponto por vírgula etc.
Quando tento fazer isso:
for i in images/*; do echo ${{i/jpg/png}/file/image}; done
Não funciona. Não consegui encontrar nenhuma outra solução ou ideia. Isso é possível -se for, como?
Comentários
- Não ' não sei por que isso não ' funcionou no bash, mas as substituições aninhadas funcionam exatamente como você esperava no zsh. Dependendo do seu ambiente, você pode considerar o uso de um melhor shell;)
Resposta
A abordagem simples seria atribuir o resultado a uma variável e, em seguida, trabalhar com essa variável. Exemplo:
for filename in images/* do echo "filename is now $filename" filename=${filename/jpg/png}; echo "filename is now $filename" filename=${filename/file/image}; echo "filename is now $filename" echo "final filename is ${filename}" done
Comentários
- Esta resposta não está completa. as substituições serão aplicadas em qualquer lugar nas strings de nome de arquivo. Com base na pergunta, Kubilay deseja substituir um prefixo e uma extensão (sufixo). você pode modificar e levar isso em consideração : $ {var / # Padrão / Substituição} Se o prefixo de var corresponder ao Padrão, então substitua Substituição por Padrão. $ {var /% Padrão / Substituição} Se o sufixo de var corresponde a Padrão, então substitua Substituição por Padrão.
- @rMistero Não ' s nenhuma regra contra postar outra resposta só porque uma resposta foi aceita. Na verdade, acho que você deveria, especialmente porque a semântica do que você está propondo é diferente. Dito isso, esta é a maneira de fazer o que o OP disse depois de tentar, então, mesmo que haja outros resultados que também possam ser válidos, acredito que é seguro presumir que isso está de acordo com o que o OP queria realizar.
Resposta
Você pode atribuir a substituição anterior a uma variável e executar a substituição dessa variável
for i in images/* do j=${i/jpg/png} echo ${j/file/image} done
Comentários
- Não tenho certeza se isso funcionar. " para i em imagens / *; fazer j = {i / jpg / png} echo $ {j / arquivo / imagem}; done " ecoa " {i / jpg / png} " repetidamente.
- Agora sim: " para i em images / *. jpg; faça j = $ {i / jpg / png}; echo $ {j / arquivo / imagem}; concluído ". Obrigado!
Responda
para alterar qualquer string :
$ echo "images/file_name_1.jpg" | perl -pE "s/file/image/;s/jpg$/png/;" images/image_name_1.png
um atalho para renomear (que pode ser o objetivo final:
$ rename "s/file/image/;s/jpg$/png/;" "$i"
Comentários
- Eu ainda acho que invocar o Perl uma vez para cada arquivo é um exagero, mas pelo menos agora isso dá uma resposta à pergunta. 🙂
- @MichaelKj ö rling Você não ' precisa invocar o Perl para cada arquivo, você pode fazer
rename … images/*
. Mas isso requer uma distribuição baseada em Debian (rename
em outras variantes do Linux é um comando completamente diferente). - @Gilles Eu estava pensando mais sobre a primeira versão, particularmente porque não há ' nada na pergunta sobre como renomear arquivos. A versão original (edição do período de tolerância) desta resposta tinha apenas a
rename
sugestão de comando.