Benennen Sie eine Gruppe von Dateien mit einem Befehl um

38

Wie kann ich eine Dateigruppe mit der Erweiterung .htm in .html umbenennen?

mv *.htm *.html

funktioniert nicht.

Richard Hoskins
quelle
Nur der Vollständigkeit halber ren *.htm *.htmlwird in Windows arbeiten.
Brian Burns

Antworten:

50

Oder Sie könnten reine Bash verwenden ... (außer MV, das ist ..)

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

und vermeiden Sie die bösen Basisnamen Zeug. ;)

Bash bietet eine Vielzahl variabler Erweiterungsoptionen. Der hier verwendete Wert '%' entfernt das kleinste übereinstimmende Suffix aus dem Wert der Variablen. Das Muster ist ein Glob-Muster, ${file%.*}würde also auch funktionieren. Der Operator '%%' entfernt das größte übereinstimmende Suffix und ist im obigen Beispiel austauschbar, da das Muster festgelegt ist, ${file%%.*}.htmlwürde er jedoch abhtm in a.html umwandeln.

Weitere nützliche Tricks finden Sie im Abschnitt zur variablen Substitution auf der bash-Manpage. Es gibt eine Menge, die direkt in bash erledigt werden kann.

falstro
quelle
1
Beachten Sie auch, dass diese Parametererweiterungen nicht auf bash beschränkt sind . Sie sind für alle von Borowski abgeleiteten Shells verfügbar ( sh , ksh , bash , zsh , dash , ash usw.). Die Erweiterungen sind Teil der POSIX-Spezifikation für die „Shell Command Language“ und können problemlos portiert werden.
Chris Johnsen
11

Die Dateinamen sollten keine Leerzeichen, Zeilenumbrüche oder andere Leerzeichen enthalten, aber diese Version von freiheit's answer behandelt diese. $()Anstelle von Backticks werden auch Informationen zur besseren Lesbarkeit sowie andere Vorteile verwendet.

for file in *.htm
do
    mv "$file" "$(basename "$file" .htm).html"
done

Noch besser - für den speziellen Fall, dass nur das Ende hinzugefügt wird:

for file in *.htm
do
    mv "$file" "${file}l"
done
Bis auf weiteres angehalten.
quelle
11

rename(1)ist ein Perl-Dienstprogramm, das genau das tut, was Sie wollen. In diesem Fall:

rename 's/\.htm$/.html/' *htm

oder wenn Sie auch Unterverzeichnisse verwenden

(erfordert Bash 4.0 und die globstar Einstellung: shopt -s globstar)

rename 's/\.htm$/.html/' **/*htm

TRS-80
quelle
1
Das Umbenennen ist einfacher, aber kein Standard-Unix-Programm. Die ursprüngliche Frage gibt nicht an, welches Unix. Scheint an manchen Stellen "Vorname" zu sein.
freiheit
2
renamekommt mit Perl, und im Grunde kommt heutzutage jeder Unix mit Perl.
TRS-80,
3
ja, aber nicht jedes Unix enthält Hilfsprogramme wie 'Umbenennen', wenn sie Perl auf dem System installieren. OSX hat zum Beispiel keine "Umbenennung".
freiheit
1
@William: Die Double Asterisk-Syntax ist nur in Bash 4 und höher verfügbar und nur, wenn sie mit shopt -s globstaraktiviert ist (standardmäßig deaktiviert ). Außerdem haben Linux und Unix Verzeichnisse anstelle von Ordnern.
Bis auf weiteres angehalten.
6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

Probieren Sie es mit einem echovor dem mversten Mal herum.

Das Problem mit Ihrem Original ist, dass " mv *.htm *.html" das *s von der Shell verarbeitet wird, sodass der mvBefehl einfach eine Liste aller .htm- und .html-Dateien im aktuellen Verzeichnis anzeigt. Mit anderen Worten, so etwas wie " mv foo.htm bar.htm stuff.htm six.htm file.htm". mv kann nur mit mehr als 2 Argumenten umgehen, wenn das letzte ein Verzeichnis ist.

freiheit
quelle
1
Sie sollten "$ file" angeben, um Leerzeichen zu behandeln.
Richard Hoskins
Ihre Beschreibung des ursprünglichen Problems sollte stärker hervorgehoben werden. Dieses Verhalten beim Erweitern von Shell-Platzhaltern ist überraschend und nicht intuitiv für jemanden, der aus dem Windows-Land kommt. Wenn Sie verstehen, was die Shell tut, wird klar, warum die ursprüngliche Anwendung von mvnicht funktioniert.
Greg Hewgill
3

Noch ein reines Bash-Beispiel mit String-Ersetzung.

for file in *.htm; do mv $file ${file/htm/html}; done

Extra - dies ersetzt alle Vorkommen einer Zeichenkette

for file in *.htm; do mv $file ${file//htm/html}; done
Xalupadas
quelle
1

Wenn Sie Zsh verwenden , können Sie 'zmv' verwenden

Martin
quelle
1

Das beste Werkzeug ist mmv .

mmv \*.htm #1.html

Andere Anwendungsbeispiele (und andere Tools) in " GNU / Linux Command-Line Tools Summary ".

bortzmeyer
quelle
1
Ihr Anwendungsbeispiel schlägt fehl. Du musst fliehen #.
Cristian Ciupitu
Nein, es funktioniert (ich teste IMMER, bevor ich auf SuperUser poste). Die Notwendigkeit, # zu entkommen, hängt von der verwendeten Shell ab (ich verwende zsh).
bortzmeyer
0

Das Paket util-linux-ng (unter Fedora) hat einen renameBefehl ähnlich dem von TRS-80 erwähnten . Du kannst es so benutzen:

rename .htm .html *.html
Cristian Ciupitu
quelle