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.
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*.htmdo
mv "$file""$(basename "$file" .htm).html"done
Noch besser - für den speziellen Fall, dass nur das Ende hinzugefügt wird:
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`.htmldone
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.
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
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:
ren *.htm *.html
wird in Windows arbeiten.Antworten:
Oder Sie könnten reine Bash verwenden ... (außer MV, das ist ..)
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%%.*}.html
wü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.
quelle
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.Noch besser - für den speziellen Fall, dass nur das Ende hinzugefügt wird:
quelle
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
quelle
rename
kommt mit Perl, und im Grunde kommt heutzutage jeder Unix mit Perl.shopt -s globstar
aktiviert ist (standardmäßig deaktiviert ). Außerdem haben Linux und Unix Verzeichnisse anstelle von Ordnern.Probieren Sie es mit einem
echo
vor demmv
ersten Mal herum.Das Problem mit Ihrem Original ist, dass "
mv *.htm *.html
" das*
s von der Shell verarbeitet wird, sodass dermv
Befehl 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.quelle
mv
nicht funktioniert.Noch ein reines Bash-Beispiel mit String-Ersetzung.
Extra - dies ersetzt alle Vorkommen einer Zeichenkette
quelle
Wenn Sie Zsh verwenden , können Sie 'zmv' verwenden
quelle
Das beste Werkzeug ist mmv .
Andere Anwendungsbeispiele (und andere Tools) in " GNU / Linux Command-Line Tools Summary ".
quelle
#
.Das Paket util-linux-ng (unter Fedora) hat einen
rename
Befehl ähnlich dem von TRS-80 erwähnten . Du kannst es so benutzen:quelle