it-swarm.com.de

Wie benenne ich die Erweiterung für einen Stapel von Dateien um?

In einem Verzeichnis habe ich eine Reihe von *.html-Dateien.

Ich möchte sie alle in *.txt umbenennen.

Ich benutze die Bash-Shell.

413
bmw0128

Eine bessere Lösung (mit nur Bash-Funktionalität im Gegensatz zu externen Anrufen) finden Sie unter eine der anderen Antworten .


Folgendes würde tun und erfordert nicht, dass das System das Programm rename hat (obwohl Sie dies häufig auf einem System haben würden):

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

EDIT: Wie in den Kommentaren darauf hingewiesen, funktioniert dies nicht für Dateinamen mit Leerzeichen ohne korrektes Anführungszeichen (jetzt oben hinzugefügt). Wenn Sie nur an Ihren eigenen Dateien arbeiten, von denen Sie wissen, dass sie keine Leerzeichen in den Dateinamen haben, funktioniert dies. Wenn Sie jedoch etwas schreiben, das zu einem späteren Zeitpunkt wiederverwendet werden kann, überspringen Sie die richtigen Anführungszeichen nicht. 

329
Mikael Auno

Bei der Verwendung von bash sind keine externen Befehle wie sed, basename, umbenennen, expr usw. erforderlich.

for file in *.html
do
  mv "$file" "${file%.html}.txt"
done
594
ghostdog74
rename 's/\.html$/\.txt/' *.html

macht genau das, was du willst.

176
Amber

Sie möchten rename verwenden:

rename -S .html .txt *.html

Dies macht genau das, was Sie möchten - es ändert die Erweiterung von .html in .txt für alle Dateien, die *.html entsprechen.

Anmerkung: Greg Hewgill weist zu Recht darauf hin, dass dies kein bash builtin ist; und ist ein separater Linux-Befehl. Wenn Sie nur etwas unter Linux benötigen, sollte dies gut funktionieren. Wenn Sie etwas plattformübergreifendes benötigen, werfen Sie einen Blick auf eine der anderen Antworten.

85
DaveR

Dies funktionierte für mich unter OSX von .txt bis .txt_bak

find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \;
84
Steven Lizarazo

Auf einem Mac ...

  1. Installiere umbenennen wenn du nicht: brew install rename
  2. rename -S .html .txt *.html
32
izilotti

Für Ubuntu-Benutzer: 

rename 's/\.html$/\.txt/' *.html
15
Bheru Lal Lohar

Hier ist ein Beispiel für den Umbenennungsbefehl:

rename -n ’s/\.htm$/\.html/’ *.htm

Das -n bedeutet, dass es sich um einen Testlauf handelt und Dateien nicht wirklich geändert werden. Daraufhin wird eine Liste der Dateien angezeigt, die beim Entfernen von -n umbenannt würden. In diesem Fall werden alle Dateien im aktuellen Verzeichnis von einer Dateierweiterung von .htm in .html konvertiert.

Wenn die Ausgabe des obigen Testlaufs in Ordnung war, könnten Sie die endgültige Version ausführen:

rename -v ’s/\.htm$/\.html/’ *.htm

Die Option -v ist optional, sollte jedoch eingefügt werden, da dies der einzige Datensatz ist, der Änderungen enthält, die mit dem Umbenennungsbefehl vorgenommen wurden.

$ rename -v 's/\.htm$/\.html/' *.htm
3.htm renamed as 3.html
4.htm renamed as 4.html
5.htm renamed as 5.html

Der knifflige Teil in der Mitte ist eine Perl-Substitution mit regulären Ausdrücken, die unten hervorgehoben ist:

rename -v ’s/\.htm$/\.html/’ *.htm
7
A.A

Diese Frage erwähnt ausdrücklich Bash, aber wenn Sie ZSH zur Verfügung haben, ist das ziemlich einfach:

zmv '(*).*' '$1.txt'

Wenn Sie zsh: command not found: zmv bekommen, führen Sie einfach Folgendes aus:

autoload -U zmv

Und dann nochmal versuchen.

Danke an diesen Originalartikel für den Tipp über zmv.

5
Michael Leonard

Dies ist die glatteste Lösung, die ich unter OSX und Linux gefunden habe, und sie funktioniert auch mit git!

find . -name "*.js" -exec bash -c 'mv "$1" "${1%.js}".tsx' - '{}' \;

und mit git:

find . -name "*.js" -exec bash -c 'git mv "$1" "${1%.js}".tsx' - '{}' \;

5
bdombro

Nach dem Crawlen einer anderen Website endete für mich Tausende von Dateien, denen die .html-Erweiterung fehlte, und zwar in einem breiten Verzeichnis von Unterverzeichnissen.

Um sie alle in einer Aufnahme umzubenennen, mit Ausnahme der Dateien, die bereits eine .html-Erweiterung haben (die meisten von ihnen hatten überhaupt keine), funktionierte dies für mich:

cd wwwroot
find . -xtype f \! -iname *.html   -exec mv -iv "{}"  "{}.html"  \;  # batch rename files to append .html suffix IF MISSING

Im Falle des OP könnte ich das leicht ändern, um nur * .txt-Dateien umzubenennen, wie folgt:

find . -xtype f  -iname *.txt   -exec filename="{}"  mv -iv ${filename%.*}.{txt,html}  \; 

Aufgeschlüsselt (Hammerzeit!):

-iname * .txt
- Das heißt, es werden NUR Dateien berücksichtigt, die bereits mit .txt enden

mv -iv "{}. {txt, html}" - Wenn find eine {} als Dateiname übergibt, extrahiert $ {Dateiname%. *} Seinen Basisnamen ohne Erweiterung, um die Parameter in mv zu bilden. bash schreibt das {txt, html} als zwei Parameter neu, so dass der letzte Befehl ausgeführt wird als: mv -iv "filename.txt" "filename.html"

Fix jedoch nötig: Umgang mit Leerzeichen in Dateinamen

5
Marcos

Der Befehl mmv scheint diese Aufgabe sehr effizient für eine große Anzahl von Dateien auszuführen (Zehntausende in einer Sekunde). Um beispielsweise alle .xml-Dateien in .html-Dateien umzubenennen, verwenden Sie Folgendes: 

mmv ";*.xml" "#1#2.html"

der ; stimmt mit dem Pfad überein, der * stimmt mit dem Dateinamen überein und diese werden im Ersetzungsnamen als #1 und #2 bezeichnet. 

Antworten, die auf exec oder Pipes basieren, waren entweder zu langsam oder bei einer sehr großen Anzahl von Dateien fehlgeschlagen. 

4
Roko Mijic

Ein bisschen zu spät zur Party. Sie könnten es mit xargs machen:

ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {}

Oder wenn sich alle Ihre Dateien in einem Ordner befinden

ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {}
3
esp

Versuche dies

rename .html .txt *.html 

verwendungszweck: 

rename [find] [replace_with] [criteria]
3
P Sreedhar

Wenn Sie Perl bevorzugen, gibt es ein kurzes Perl-Skript (von Larry Wall, dem Ersteller von Perl), das genau das tut, was Sie hier wollen: tips.webdesign10.com/files/rename.pl.txt . Für Ihr Beispiel sollte das Folgende den Trick tun

rename.pl 's/html/txt/' *.html

=)

(Danke @loretoparisi für die aktualisierte URL)

2
dudusan

Dies ist eine gute Möglichkeit, mehrere Erweiterungen gleichzeitig zu ändern:

for fname in *.{mp4,avi}
do
   mv -v "$fname" "${fname%.???}.mkv"
done

Hinweis: Seien Sie vorsichtig, wenn die Erweiterungsgröße gleich ist (die ???).

1
Nick De Greek

Schön und einfach!

find . -iname *.html  -exec mv {} "$(basename {} .html).text"  \;
1
Deano

Hier habe ich .Edge Dateien umbenannt in .blade.php

for file in *.Edge; do     mv "$file" "$(basename "$file" .Edge).blade.php"; done

Funktioniert wie Charme.

0
Nixon Kosgei

Leider ist es nicht trivial, portabel zu handeln. Du brauchst wahrscheinlich ein bisschen Zauberkraft.

for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done

Entfernen Sie das Echo, sobald Sie zufrieden sind, dass es das tut, was Sie möchten.

Edit: basename ist für diesen speziellen Fall wahrscheinlich etwas lesbarer, obwohl expr generell flexibler ist.

0
CB Bailey

Sie können eine Funktion auch in Bash erstellen, sie zu .bashrc oder etwas anderem hinzufügen und sie dann verwenden, wo immer Sie möchten.

change-ext() {
    for file in *.$1; do mv "$file" "$(basename "$file" .$1).$2"; done
}

Verwendungszweck:

change-ext css scss

Quellcode in Funktion: https://stackoverflow.com/a/1224786/6732111

0
J Kluseczka

Eine Zeile, keine Schleifen: ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}

[email protected]:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json  ac8453e2-0d82-4d43-b80e-205edb754700.json
[email protected]:~/pgsql$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
[email protected]:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt  ac8453e2-0d82-4d43-b80e-205edb754700.txt
[email protected]:~/pgsql$ 
0