Jak v bash nahradit více než jeden podřetězec najednou?

Mám adresář obsahující obrazové soubory, které mají být ozvěny v bash. Při ozvěně chci nahradit název souboru i příponu v příkazu jednoho řádku.

Ukázkové soubory:

images/file_name_1.jpg images/file_name_2.jpg 

Obvykle mohu provést jednu náhradu takto:

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

A výstup bude vypadat takto:

 images/image_name_1.jpg images/image_name_2.jpg  

Jak jej mohu ponechat ve smyčce for a nahradit řetězec „jpg“ také „png“? Je to jen instance, mohl bych tečku nahradit čárkou atd.

Když to zkusím:

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

To nefunguje. Nemohu najít žádné jiné řešení nebo nápad. Je to možné – pokud ano, jak?

Komentáře

  • Nemám ' nevíte, proč to ' nefunguje v bash, ale vnořené náhrady fungují přesně tak, jak jste očekávali v zsh. V závislosti na vašem prostředí můžete zvážit better shell;)

Odpověď

Jednoduchým přístupem by bylo přiřadit výsledek proměnné a pak pracovat s touto proměnnou. Příklad:

 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  

Komentáře

  • Tato odpověď není úplná. Substituce se použijí kdekoli v řetězcích názvů souborů. Na základě otázky chce Kubilay nahradit předponu a příponu (příponu). Můžete to upravit a vzít v úvahu : $ {var / # Pattern / Replacement} Pokud předpona var odpovídá Pattern, pak nahraďte Replacement za Pattern. $ {var /% Pattern / Replacement} Pokud přípona var odpovídá vzoru a poté nahradí nahrazení vzoru.
  • @rMistero ' neexistuje pravidlo proti zveřejnění další odpovědi jen proto, že byla přijata odpověď. Ve skutečnosti si myslím, že byste měli, zejména proto, že sémantika toho, co navrhujete, se liší. To znamená, že toto je způsob, jak dělat to, co OP řekl, že se snažil, takže i když existují další výsledky, které by mohly být také platné, domnívám se, že je bezpečné předpokládat, že je to v souladu s tím, čeho chtěl OP dosáhnout.

Odpovědět

Předchozí proměnnou můžete přiřadit k proměnné a místo ní spustit nahrazení

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

Komentáře

  • Nevím pokud to funguje. " pro i v obrázcích / *; do j = {i / jpg / png} echo $ {j / soubor / obrázek}; done " opakovaně odráží " {i / jpg / png} ".
  • Nyní ano: " pro i v obrázcích / *. jpg; do j = $ {i / jpg / png}; echo $ {j / file / image}; hotovo ". Děkujeme!

Odpovědět

změnit libovolný řetězec :

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

zástupce k přejmenování (což může být konečný cíl:

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

komentáře

  • Stále si myslím, že vyvolání Perlu pro každý soubor je přehnané, ale přinejmenším teď to dává odpověď na otázku. 🙂
  • @MichaelKj ö rling Nemusíte ' vyvolat Perl pro každý soubor, můžete rename … images/*. To ale vyžaduje distribuci založenou na Debianu (rename u jiných variant Linuxu je úplně jiný příkaz).
  • @Gilles Přemýšlel jsem více o první verzi, zejména proto, že v otázce ' není nic o otázce ohledně přejmenování souborů. Původní verze (upravená s ochrannou lhůtou) této odpovědi měla pouze rename návrh příkazu.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *