Hvordan udskiftes mere end en substring på én gang i bash?

Jeg har en mappe, der indeholder billedfiler, der skal gentages i bash. Mens jeg ekko, vil jeg erstatte både filnavn og udvidelse i en enkelt linjekommando.

Eksempler på filer:

images/file_name_1.jpg images/file_name_2.jpg 

Normalt kan jeg udskifte en sådan måde:

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

Og output bliver som:

 images/image_name_1.jpg images/image_name_2.jpg  

Hvordan kan jeg holde det i loop og udskifte “jpg” -strengen til “png” også? Det er bare en forekomst, jeg kunne erstatte prikken til komma osv.

Når jeg prøver dette:

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

Det virker ikke. Jeg kan ikke finde nogen anden løsning eller idé. Er det muligt – hvis det er tilfældet?

Kommentarer

  • Jeg don ' ved ikke, hvorfor dette ikke fungerede ', men indlejrede erstatninger fungerer ligesom du forventede i zsh. Afhængigt af dit miljø kan du overveje at bruge en bedre skal;)

Svar

Den enkle tilgang ville være at tildele resultatet til en variabel og derefter arbejde med den variabel. 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 svar er ikke komplet. udskiftningerne gælder hvor som helst i filnavnstrengene. Baseret på spørgsmålet ønsker Kubilay at erstatte et præfiks og en udvidelse (suffiks). kan du ændre og tage dette i betragtning : $ {var / # Mønster / Erstatning} Hvis præfikset for var matcher Mønster, skal du erstatte Erstatning med Mønster. $ {var /% Mønster / Udskiftning} Hvis suffikset af var matcher mønster, og erstat derefter Erstatning for mønster.
  • @rMistero Der ' er ingen regel mod at sende et andet svar, bare fordi et svar er blevet accepteret. Faktisk synes jeg, du burde, især da semantikken i det, du foreslår, er forskellig. Når det er sagt, er det sådan, man skal gøre, hvad OP sagde efter at have prøvet, så selvom der er andre resultater, der også kan være gyldige, tror jeg, det er sikkert at antage, at dette er i tråd med, hvad OP ønskede at opnå. / li>

Svar

Du kan tildele den tidligere erstatning til en variabel og køre erstat på den variabel i stedet

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

Kommentarer

  • Ikke sikker hvis det virker. " for i i billeder / *; gør j = {i / jpg / png} ekko $ {j / fil / billede}; gjort " gentager " {i / jpg / png} " gentagne gange.
  • Nu ja: " for i i billeder / *. jpg; gør j = $ {i / jpg / png}; ekko $ {j / fil / billede}; gjort ". Tak!

Svar

for at ændre enhver streng :

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

en genvej til omdøbning (hvilket kan være det ultimative mål:

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

Kommentarer

  • Jeg synes stadig, at det er for meget at påkalde Perl én gang for hver fil, men i det mindste nu giver dette svar på spørgsmålet. 🙂
  • @MichaelKj ö rling Du behøver ikke ' for at påkalde Perl for hver fil, du kan gøre rename … images/*. Men dette kræver en Debian-baseret distribution (rename på andre Linux-varianter er en helt anden kommando).
  • @Gilles Jeg tænkte mere på den første version, især da der ' ikke er noget i spørgsmålet som stillet om omdøbning af filer. Den oprindelige (redigerede behandlingsperiode) version af dette svar havde kun rename kommandoforslaget.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *