dodawanie tekstu do nazwy pliku przed rozszerzeniem

25

Chciałbym dodać tekst na końcu nazwy pliku, ale przed rozszerzeniem. Teraz próbuję

for f in *.shp; do echo $f_poly; done

wynik jest,

Quercus_acutifolia.shp_poly
Quercus_agrifolia.shp_poly
Quercus_corrugata.shp_poly
Quercus_cortesii.shp_poly
Quercus_costaricensis.shp_poly
Quercus_havardii.shp_poly
Quercus_hemisphaerica.shp_poly
Quercus_kelloggii.shp_poly
Quercus_knoblochii.shp_poly
Quercus_laceyi.shp_poly

Chcę, żeby tak było

Quercus_acutifolia_poly.shp
Quercus_agrifolia_poly.shp
Quercus_corrugata_poly.shp
Quercus_cortesii_poly.shp
Quercus_costaricensis_poly.shp
Quercus_havardii_poly.shp
Quercus_hemisphaerica_poly.shp
Quercus_kelloggii_poly.shp
Quercus_knoblochii_poly.shp
Quercus_laceyi_poly.shp
Sam007
źródło

Odpowiedzi:

27

Używając standardowego rozszerzenia parametrów POSIX :

for f in *.shp; do printf '%s\n' "${f%.shp}_poly.shp"; done
jw013
źródło
Niesamowite, właśnie tego potrzebowałem.
Sam007,
1
Może być lepiej z wyjaśnieniem, jak to działa. Z drugiej strony odpowiedź Douga jest dość łatwa.
Sarge Barszcz
@SargeBorsch Co potrzebujesz wyjaśnienia? Moja odpowiedź, fragment pytania i odpowiedź Douga różnią się tylko kilkoma postaciami, a odpowiedź Douga wyjaśnia nawet mniej niż moja, więc nie wiem, czego chcesz. Jeśli po prostu porównasz różnicę między dwoma wyjściami w pytaniu, łatwo będzie dowiedzieć się, co robią. Mogę wyjaśnić, dlaczego moja odpowiedź jest lepsza niż odpowiedź Douga. 1. Używam printfz ciągiem formatu zamiast mniej przenośnego echo. 2. Używam rozszerzenia parametrów, które jest bardziej wydajne niż wywołanie zewnętrznego pliku binarnego ( basename) dla tak prostego zadania.
jw013
Następnie polecenie zmiany nazwy plików byłoby następujące:for f in *.shp; do mv $f ${f%.shp}_poly.shp; done
Patch92
6

Czasami jest zainstalowane narzędzie o nazwie „zmiana nazwy”.

rename 's/\.shp$/_poly.shp/' *shp

Może nie być przenośny, ale jest łatwy w użyciu.

Chad Clark
źródło
1
To jedyny, który dla mnie zadziałał, świetna odpowiedź!
wanderer0810,
4

Użyj tego:

for file in *.shp; do echo $(basename $file .shp)_poly.shp; done
doneal24
źródło
3
Użycie basenamejest wolniejsze i mniej wydajne niż pozwolenie powłoce na samodzielne wykonanie pracy. Może to być zauważalne w przypadku bardzo dużej liczby plików.
jw013,
Ponadto brakuje cudzysłowów i --s, a nazwy plików, które mają znaki nowej linii przed .shp.
Stéphane Chazelas
Dzięki za udzielenie odpowiedzi, z którą właściwie mogę pracować dla swoich celów. To jest pomoc bash, nie kod golfa. (czytając to .. Zdaję sobie sprawę, może to brzmieć jak byłem sarkastyczny Więcej chwytania o innych odpowiedzi na tutaj niż twoje Dzięki jeszcze raz.).
Tim
3

To działało dla mnie lepiej:

for f in *; do NEW=${f%.webm}_2016.webm; mv ${f} "${NEW}"; done

Vinnie James
źródło
Cóż, to wygląda bardzo podobnie do zaakceptowanej odpowiedzi, z wyjątkiem tego, że prawdopodobnie chcesz for f in *.webm, zapomniałeś zacytować ${f}i brakuje --.
Stéphane Chazelas
1
Przyjęta odpowiedź nie działa w systemie OSX, drukuje tylko nowe nazwy plików, w rzeczywistości nie zmienia nazw plików
Vinnie James
1
Oczywiście pokazuje, jak używać rozszerzeń powłoki, aby uzyskać nową nazwę pliku, w odpowiedzi na pytanie, które również wypisuje nazwę pliku (z echo), ale nie wymaganą.
Stéphane Chazelas
1

Jeśli znajdują się w różnych lokalizacjach, uruchom:

for i in ` find /root/test/ -name "*.shp" ` ;
do
  mv $i ` echo $i | sed 's/.shp$/_poly.shp/g' ` ;
done
Shankey Ravi
źródło
1

Ponieważ pytanie brzmi, bashnie ma potrzeby używania zewnętrznych narzędzi, ponieważ można użyć wyrażeń regularnych bash :

for i in *.shp
do
    mv -v "${i}" "${i%.*}_MYSUFFIX.${i##*.}"
done
ccpizza
źródło