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

Odpowiedzi:


27

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

for f in *.shp; do printf '%s\n' "${f%.shp}_poly.shp"; done

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.


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

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


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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.