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.