Cum se pot înlocui mai multe sub-șiruri simultan în bash?

Am un director care conține fișiere imagine care urmează să fie redate în bash. În timp ce ecou, vreau să înlocuiesc atât numele fișierului cât și extensia într-o singură linie de comandă.

Exemplu de fișiere:

images/file_name_1.jpg images/file_name_2.jpg 

În mod normal, pot face o singură înlocuire astfel:

 for i in images/*; do echo ${i/file/image}; done  

Și ieșirea devine ca:

 images/image_name_1.jpg images/image_name_2.jpg  

Cum pot să-l păstrez în buclă și să înlocuiesc șirul „jpg” cu „png”? Este doar o instanță, aș putea înlocui punctul cu virgulă etc.

Când încerc asta:

 for i in images/*; do echo ${{i/jpg/png}/file/image}; done  

Nu funcționează. Nu pot găsi nici o altă soluție sau idee. Este posibil acest lucru -dacă așa, cum?

Comentarii

  • Nu ' nu știu de ce acest lucru nu ' nu a funcționat în bash, dar înlocuirile imbricate funcționează exact așa cum vă așteptați în zsh. shell mai bun;)

Răspuns

Abordarea simplă ar fi să atribuiți rezultatul unei variabile, apoi să lucrați cu acea variabilă. Exemplu:

 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  

Comentarii

  • Acest răspuns nu este complet. substituțiile se vor aplica oriunde în șirurile de nume de fișiere. Pe baza întrebării, Kubilay dorește să înlocuiască un prefix și o extensie (sufix). Puteți modifica și lua în considerare acest lucru : $ {var / # Pattern / Replacement} Dacă prefixul var se potrivește cu Pattern, înlocuiți Înlocuirea cu Pattern. $ {var /% Pattern / Replacement} Dacă sufixul var se potrivește cu modelul, apoi înlocuiește înlocuirea cu modelul.
  • @rMistero Nu există ' regulă împotriva postării unui alt răspuns doar pentru că a fost acceptat un răspuns. De fapt, cred că ar trebui, mai ales că semantica a ceea ce propuneți este diferită. Acestea fiind spuse, aceasta este modalitatea de a face ceea ce a încercat PO, așa că, chiar dacă există și alte rezultate care ar putea fi valabile, cred că este sigur să presupunem că acest lucru este în concordanță cu ceea ce OP a dorit să realizeze. / li>

Răspuns

Puteți atribui înlocuirea anterioară unei variabile și puteți rula înlocuirea pe acea variabilă

 for i in images/* do j=${i/jpg/png} echo ${j/file/image} done  

Comentarii

  • Nu sunt sigur dacă funcționează. " pentru i în imagini / *; face j = {i / jpg / png} ecou $ {j / file / image}; done " ecouri " {i / jpg / png} " în mod repetat.
  • Acum da: " pentru i în imagini / *. jpg; faceți j = $ {i / jpg / png}; ecou $ {j / file / image}; făcut ". Mulțumim!

Răspunde

pentru a schimba orice șir :

$ echo "images/file_name_1.jpg" | perl -pE "s/file/image/;s/jpg$/png/;" images/image_name_1.png 

o comandă rapidă pentru redenumire (care poate fi obiectivul final:

$ rename "s/file/image/;s/jpg$/png/;" "$i" 

Comentarii

  • Încă cred că invocarea Perl o dată pentru fiecare fișier este exagerată, dar cel puțin acum acest lucru oferă un răspuns la întrebare. 🙂
  • @MichaelKj ö rling Nu ' nu trebuie să invocați Perl pentru fiecare fișier, puteți face rename … images/*. Dar acest lucru necesită o distribuție bazată pe Debian (rename pe alte variante Linux este o comandă complet diferită).
  • @Gilles Mă gândeam mai mult la prima versiune, mai ales că ' nu este nimic în întrebare ca întrebat despre redenumirea fișierelor. Versiunea originală (perioada de grație editată) a acestui răspuns a avut doar sugestia de comandă rename.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *