Jai un répertoire contenant des fichiers image qui doivent être repris dans bash. En écho, je souhaite remplacer à la fois le nom et lextension du fichier dans la commande sur une seule ligne.
Exemples de fichiers:
images/file_name_1.jpg images/file_name_2.jpg
Normalement, je peux faire un remplacement simple comme ceci:
for i in images/*; do echo ${i/file/image}; done
Et le résultat devient comme:
images/image_name_1.jpg images/image_name_2.jpg
Comment puis-je le garder dans la boucle for et remplacer la chaîne « jpg » par « png » également? Cest juste une instance, je pourrais remplacer le point par une virgule, etc.
Quand jessaye ceci:
for i in images/*; do echo ${{i/jpg/png}/file/image}; done
Cela ne fonctionne pas. Je ne peux trouver aucune autre solution ou idée. Est-ce possible -si oui, comment?
Commentaires
- Je ne ' Je ne sais pas pourquoi cela ' t fonctionne dans bash, mais les remplacements imbriqués fonctionnent exactement comme prévu dans zsh. En fonction de votre environnement, vous pouvez envisager d’utiliser un meilleur shell;)
Réponse
Lapproche simple serait dassigner le résultat à une variable, puis de travailler avec cette variable. Exemple:
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
Commentaires
- Cette réponse nest pas complète. les substitutions sappliqueront nimporte où dans les chaînes du nom de fichier. En fonction de la question, Kubilay souhaite remplacer un préfixe et une extension (suffixe). pouvez-vous modifier et prendre cela en considération : $ {var / # Pattern / Replacement} Si le préfixe de var correspond à Pattern, remplacez le modèle par Replacement. $ {var /% Pattern / Replacement} Si suffixe de var correspond à Pattern, puis remplacez Replacement par Pattern.
- @rMistero Il ny a ' aucune règle contre la publication dune autre réponse simplement parce quune réponse a été acceptée. En fait, je pense que vous devriez, dautant plus que la sémantique de ce que vous proposez est différente. Cela dit, cest la façon de faire ce que le PO a dit après avoir essayé, donc même sil y a dautres résultats qui pourraient également être valides, je pense quil est prudent de supposer que cela est conforme à ce que le PO voulait accomplir.
Réponse
Vous pouvez affecter le remplacement précédent à une variable et exécuter replace sur cette variable à la place
for i in images/* do j=${i/jpg/png} echo ${j/file/image} done
Commentaires
- Incertain si ça marche. " pour i en images / *; faire j = {i / jpg / png} echo $ {j / fichier / image}; done " fait écho " {i / jpg / png} " à plusieurs reprises.
- Maintenant oui: " pour i dans les images / *. jpg; faire j = $ {i / jpg / png}; echo $ {j / fichier / image}; terminé ". Merci!
Répondez
pour modifier nimporte quelle chaîne :
$ echo "images/file_name_1.jpg" | perl -pE "s/file/image/;s/jpg$/png/;" images/image_name_1.png
un raccourci pour renommer (qui peut être le but ultime:
$ rename "s/file/image/;s/jpg$/png/;" "$i"
Commentaires
- Je pense toujours quinvoquer Perl une fois pour chaque fichier est excessif, mais au moins maintenant cela donne une réponse à la question. 🙂
- @MichaelKj ö rling Vous navez ' pas besoin dappeler Perl pour chaque fichier, vous pouvez faire
rename … images/*
. Mais cela nécessite une distribution basée sur Debian (rename
sur les autres variantes de Linux est une commande complètement différente). - @Gilles Je pensais plus à la première version, dautant plus quil ny a ' rien dans la question posée sur le changement de nom des fichiers. La version originale (période de grâce modifiée) de cette réponse ne contenait que la suggestion de commande
rename
.