Hinzufügen von Text zum Dateinamen vor der Erweiterung

25

Ich möchte Text am Ende des Dateinamens aber vor der Erweiterung einfügen. Im Moment versuche ich,

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

die Ausgabe ist,

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

Ich möchte, dass es so ist,

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
quelle

Antworten:

27

Verwendung der Standard-POSIX-Parametererweiterung :

for f in *.shp; do printf '%s\n' "${f%.shp}_poly.shp"; done
jw013
quelle
Genial, genau das habe ich gebraucht.
Sam007,
1
Könnte mit einer Erklärung, wie es funktioniert, besser sein. Die Antwort von Doug ist dagegen ziemlich einfach.
Sarge Borsch
@SargeBorsch Was brauchst du erklärt? Meine Antwort, der Ausschnitt in der Frage und Dougs Antwort unterscheiden sich nur um ein paar Zeichen, und Dougs Antwort erklärt noch weniger als meine, sodass ich nicht weiß, was Sie wollen. Wenn Sie nur den Unterschied zwischen den beiden Ausgängen in der Frage vergleichen, sollte es trivial einfach sein, herauszufinden, was sie tun. Ich kann erklären, warum meine Antwort Doug vorzuziehen ist. 1. Ich verwende printfeine Formatzeichenfolge anstelle der weniger portablen echo. 2. Ich verwende eine Parametererweiterung, die effizienter ist als das Aufrufen einer externen Binärdatei ( basename) für eine so einfache Aufgabe.
JW013
Der Befehl zum Umbenennen der Dateien for f in *.shp; do mv $f ${f%.shp}_poly.shp; done
lautet dann
6

Manchmal ist ein Tool namens "Umbenennen" installiert.

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

Es ist möglicherweise nicht portabel, aber einfach zu bedienen.

Chad Clark
quelle
1
Dies ist die einzige, die für mich funktioniert hat, tolle Antwort!
Wanderer0810
4

Benutze das:

for file in *.shp; do echo $(basename $file .shp)_poly.shp; done
doneal24
quelle
3
Die Verwendung basenameist langsamer und weniger effizient, als die Shell die Arbeit alleine erledigen zu lassen. Dies kann bei sehr vielen Dateien auffallen.
JW013
Außerdem fehlen Anführungszeichen und Anführungszeichen, und --Dateinamen mit Zeilenumbrüchen vor dem .shp.
Stéphane Chazelas
Vielen Dank für die Antwort, mit der ich für meinen Zweck arbeiten kann. Dies ist Bash-Hilfe, kein Code-Golf. (Lies darüber. Mir ist klar, dass es sich angehört hat, als wäre ich sarkastisch. Die anderen Antworten hier sind spannender als deine.
Tim,
3

Das hat bei mir besser funktioniert:

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

Vinnie James
quelle
Nun, das sieht der akzeptierten Antwort sehr ähnlich, mit der Ausnahme, dass Sie wahrscheinlich möchten for f in *.webm, vergessen haben, die zu zitieren, ${f}und dass Ihnen eine fehlt --.
Stéphane Chazelas
1
Die akzeptierte Antwort funktioniert unter OSX nicht, es werden nur die neuen Dateinamen ausgedruckt, die Dateien werden nicht umbenannt
Vinnie James,
1
Natürlich zeigt es Ihnen, wie Sie Shell-Erweiterungen verwenden, um den neuen Dateinamen zu erhalten, als Antwort auf die Frage, die auch einen Dateinamen (mit echo) ausgibt , aber nicht den erforderlichen.
Stéphane Chazelas
1

Wenn sie sich an verschiedenen Orten befinden, führen Sie Folgendes aus:

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

Da die Frage ist, bashbesteht keine Notwendigkeit für externe Dienstprogramme, da Sie verwenden können bash regexps verwenden können :

for i in *.shp
do
    mv -v "${i}" "${i%.*}_MYSUFFIX.${i##*.}"
done
ccpizza
quelle