Hvordan erstatter mer enn ett underlag på bash?

Jeg har en katalog som inneholder bildefiler som skal ekko i bash. Mens jeg ekko, vil jeg erstatte både filnavn og utvidelse i en linjekommando.

Eksempelfiler:

images/file_name_1.jpg images/file_name_2.jpg 

Normalt kan jeg utskifte enkelt slik:

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

Og utgangen blir som:

 images/image_name_1.jpg images/image_name_2.jpg  

Hvordan kan jeg holde det inne for løkke og erstatte «jpg» -strengen til «png» også? Det er bare en forekomst, jeg kan erstatte prikken til komma osv.

Når jeg prøver dette:

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

Det fungerer ikke. Jeg kunne ikke finne noen annen løsning eller idé. Er dette mulig – hvis det er slik?

Kommentarer

  • Jeg don ' vet ikke hvorfor dette ikke fungerte ', men nestede erstatninger fungerer akkurat som du forventet i zsh. Avhengig av miljøet ditt, kan du vurdere å bruke en bedre skall;)

Svar

Den enkle tilnærmingen vil være å tildele resultatet til en variabel, og deretter jobbe med den variabelen. Eksempel:

 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  

Kommentarer

  • Dette svaret er ikke komplett. erstatningene vil gjelde hvor som helst i filnavnstrengene. Basert på spørsmålet ønsker Kubilay å erstatte et prefiks og en utvidelse (suffiks). kan du endre og ta dette med : $ {var / # Mønster / Erstatning} Hvis prefikset til var samsvarer med Mønster, erstatt Erstatning med Mønster. $ {var /% Mønster / Erstatning} Hvis suffikset av var samsvarer med Mønster, og erstatt deretter Erstatning for Mønster.
  • @rMistero Det ' er ingen regel mot å legge ut et annet svar bare fordi et svar er godtatt. Faktisk tror jeg du burde, spesielt siden semantikken til det du foreslår er forskjellig. Når det er sagt, dette er måten å gjøre det OP sa etter å ha prøvd, så selv om det er andre resultater som også kan være gyldige, tror jeg det er trygt å anta at dette er i tråd med det OP ønsket å oppnå. / li>

Svar

Du kan tilordne den forrige erstatningen til en variabel og kjøre erstatt på den variabelen i stedet

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

Kommentarer

  • Ikke sikker hvis det fungerer. " for i i bilder / *; gjør j = {i / jpg / png} ekko $ {j / fil / bilde}; gjort " ekko " {i / jpg / png} " gjentatte ganger.
  • Nå ja: " for i i bilder / *. jpg; gjør j = $ {i / jpg / png}; ekko $ {j / file / image}; gjort ". Takk!

Svar

for å endre hvilken som helst streng :

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

en snarvei for å gi nytt navn (som kan være det endelige målet:

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

Kommentarer

  • Jeg tror fremdeles å påkalle Perl en gang for hver fil er for mye, men i det minste gir dette i hvert fall svar på spørsmålet. 🙂
  • @MichaelKj ö rling Du trenger ikke ' for å påkalle Perl for hver fil, du kan gjøre rename … images/*. Men dette krever en Debian-basert distribusjon (rename på andre Linux-varianter er en helt annen kommando).
  • @Gilles Jeg tenkte mer på den første versjonen, spesielt siden det ' ikke er noe i spørsmålet som blir spurt om å gi nytt navn til filer. Den opprinnelige (redigerte nådeperioden) versjonen av dette svaret hadde bare rename kommandoforslaget.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *