Rekursywnie zmieniaj rozszerzenia plików w Bash

87

Chcę rekurencyjnie przechodzić przez katalog i zmieniać rozszerzenia wszystkich plików o określonym rozszerzeniu, powiedzmy .t1na .t2. Jakie polecenie bash służy do tego?

Amal Antony
źródło
14
imho to nie jest zduplikowane pytanie - drugie pytanie nie jest rekurencyjne
shonky użytkownik linuxa
Związane z: askubuntu.com/questions/35922/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@AmalAntony: Jeśli nie masz rename, napisz skrypt powłoki, który zmienia nazwę pojedynczego pliku (jest to trywialne w twoim prostym przypadku), a następnie użyj findtego skryptu, aby zastosować ten skrypt do wszystkich plików z naruszającym rozszerzeniem.
user1934428

Odpowiedzi:

208

Jeśli masz możliwość zmiany nazwy, użyj:

find . -name "*.t1" -exec rename 's/\.t1$/.t2/' '{}' +

albo:

find . -name '*.t1' -exec rename .t1 .t2 {} +

Jeśli zmiana nazwy nie jest dostępna, użyj:

find . -name "*.t1" -exec bash -c 'mv "$1" "${1%.t1}".t2' - '{}' +
anubhava
źródło
20
find . -name '*.t1' -exec rename .t1 .t2 {} +
Aaron Blenkush
2
(Moja wersja renamenie pozwala na wyrażenie podstawienia w stylu seda. Uwielbiam Linuksa. Kiedyś musiałem instalować TotalCommander dla Windows, aby robić takie rzeczy.)
Aaron Blenkush
6
Na wypadek, gdyby ktoś się zastanawiał, co "${1%.t1}".t2robi ta część, tak jak ja: Używa operacji na łańcuchach basha, aby wykonać następujące czynności: 1 / Weź pierwszy parametr pozycyjny $1i obetnij .t1literał ciągu od jego końca ( %operator znaku procentu ). 2 / Dołącz .t2literał ciągu do wyniku.
Zack,
2
Zmiana nazwy nie zadziałała dla mnie w OSX, ale wersja bash jest niesamowita b / c Właśnie dodałem
``
3
wolą użytkowników find . -type f -name '*.t1'unikać folderów
Golak Sarangi
9

Jeśli Twoja wersja bashobsługuje tę globstaropcję (wersja 4 lub nowsza):

shopt -s globstar
for f in **/*.t1; do
    mv "$f" "${f%.t1}.t2"
done 
Chepner
źródło
7

Lub możesz po prostu zainstalować mmvpolecenie i wykonać:

mmv '*.t1' '#1.t2'

Oto #1pierwsza część globu, czyli *in *.t1.

Lub w czystym bashu, prostym sposobem byłoby:

for f in *.t1; do
    mv "$f" "${f%.t1}.t2"
done

(tj .: formoże wyświetlać pliki bez pomocy zewnętrznego polecenia, takiego jak lslub find)

HTH

zmo
źródło
7
Zakładam, że użycie przez OP "rekurencyjnie" odnosi się również do zmiany nazw plików w podkatalogach katalogu.
chepner
1
to pierwsza część **.t1
globalna,
6

Zrobiłbym tak w bash:

for i in $(ls *.t1); 
do
    mv "$i" "${i%.t1}.t2" 
done

EDYCJA: mój błąd: to nie jest rekurencyjne, oto mój sposób na rekurencyjną zmianę nazwy pliku:

for i in $(find `pwd` -name "*.t1"); 
do 
    mv "$i" "${i%.t1}.t2"
done
jrjc
źródło
8
Nie analizuj ls i zobacz tę samą stronę, aby dowiedzieć się, dlaczego twoja findskładnia jest zła. Upewnij się również, że cytowałeś swoje zmienne
Przywróć Monikę Proszę,