Ersetzen Sie alle Doppelpunkte aus Dateinamen durch Terminal

12

Ich habe Musik im Wert von GB auf meiner Festplatte, die mit EXT4 formatiert wurde. Ich möchte diese Dateien auf eine FAT-formatierte Festplattenpartition verschieben. Ich kann jedoch die meisten meiner Dateien nicht verschieben, da die Namen ":" enthalten (z. B. "Akt 2: ....." für Opern). Gibt es eine Möglichkeit mit der Befehlszeile, alle meine Dateien von "XXXX: XXXX" in "XXXX-XXXX" umzubenennen?

Ryan McClure
quelle

Antworten:

24

Wenn sich alle Ihre Dateien in einem einzigen Verzeichnis befinden, versuchen Sie Folgendes:

rename 's|:|-|g' *

(wobei * in etwas restriktiveres geändert werden kann, wenn Sie möchten)

Wenn Sie viele Dateien in einem Verzeichnisbaum haben, versuchen Sie dies von der Basis des Baums aus:

find . -name "*:*" -exec rename 's|:|-|g' {} \;

Sie können die Option -ndirekt danach hinzufügen rename, damit sie Ihnen sagt, was sie tun würde, ohne es tatsächlich zu tun. Dies kann Ihnen helfen, zu vermeiden, dass Sie versehentlich auf andere Dateien oder etwas anderes Schlechtes treten ...

AeroGT80
quelle
1
Einzelverzeichnislösung funktioniert, verschachtelte Lösung jedoch nicht, wenn Verzeichnisse selbst: s in ihren Namen haben. Dies liegt daran, dass in der Ausgabe des find .Namens eines Unterverzeichnisses dessen Inhalt vorangestellt ist. Also , wenn Sie eine Datei /1:/2:zuerst /1:/wird umbenannt /1-/. Jetzt können Sie nicht umbenennen /1:/2:, /1-/2-da /1:/2:es nicht existiert.
S Prasanth
1
Für Verzeichnisse: find . -type d -readable -writable -exec rename 's|:|-|g' {} \;Und dann Dateien:find . -type f -readable -writable -exec rename 's|:|-|g' {} \;
@Christopher Der Befehl für Verzeichnisse schlägt fehl, wenn zwei Verzeichnisebenen vorhanden sind: in ihren Namen. Beispiel: / 1: / 2: / wobei 2: auch ein Verzeichnis ist. Wenn dies in Ryans Situation nicht der Fall ist, funktioniert dies natürlich.
S Prasanth
Verwenden Sie für mehrere Ebenen von Unterverzeichnissen : for i in {1..20}; do find . -maxdepth $i -mindepth $i -name "*:*" -exec rename 's|:|-|g' {} \;; done. Ändern Sie 20 auf die maximale Tiefe des Verzeichnisses. Struktur. Muss nicht genau sein - kann größer sein. Wird einige Zeit dauern, wenn eine sehr große Anzahl eingestellt ist.
S Prasanth
0

Ich bin gerade nicht auf meinem Linux-Rechner, daher kann ich nur grobe Informationen geben.

Linux verfügt über ein Befehlszeilenprogramm, renamedas unter anderem mit Eingaben, regulären Ausdrücken oder regulären Ausdrücken funktioniert. Sie sollten dies zusammen mit einem regulären Ausdruck wie "s /: / - /" für Ihre Dateien verwenden können, um die gewünschte Umbenennung zu erreichen.

Um sicher zu gehen, machen Sie es in kleinen Stapeln und / oder testen Sie es zuerst mit der Simulation (Umbenennen hat ein Flag, das Ihnen nur den alten und den neuen Namen der Datei gibt, ohne sie tatsächlich umzubenennen - verwenden Sie dies, um dies zuerst zu überprüfen).

Karthik T.
quelle
0

Dies ist eine Lösung in Python, die den Fall behandelt, dass sich die Dateien nicht unbedingt im selben Verzeichnis befinden.

import os
torename = []
rootdir = "The main directory"
logfile = "Path to log file" #Eg: logfile = "/home/prasanth/renamelog"
for (path, dirs, files) in os.walk(rootdir):
    for dirname in dirs:
        if ':' in dirname:
            torename.append(os.path.join(path, dirname))
    for filename in files:
        if ':' in filename:
            torename.append(os.path.join(path, filename))

print "No of files/dirs to rename =", len(torename)
a = raw_input("Continue? (y/n) ")
if a == 'y':
    torename.reverse()
    for oldname in torename:
        directory, filename = os.path.split(oldname)
        newname = os.path.join(directory, filename.replace(':', '-'))
        command = 'mv %s %s > /dev/null' % (repr(oldname), repr(newname))
        os.system(command)
        f = open(logfile, 'a')
        f.write(oldname + '\n')
        f.close()
else:
    print "Aborted."
  1. Speichern Sie dies in einer Datei (sagen wir) rename.py.
  2. Wechseln Sie rootdirin das äußerste betrachtete Verzeichnis (Verwenden Sie den vollständigen Pfadnamen beginnend mit /. Keine Kurz- oder Umgebungsvariablen wie ~ erlaubt). Sie müssen \ nicht vor Sonderzeichen setzen - zum Beispiel, wenn das äußerste Verzeichnis /.../Meine Festplatte ist, setzen Sie rootdir = "/.../My HDD"NOT rootdir = "/.../My\ HDD"(Beachten Sie die "s) [Ich bin dies nur explizit, weil Sie mit Python möglicherweise nicht vertraut sind. Keine Respektlosigkeit beabsichtigt.]
  3. Wechseln Sie logfilezum gewünschten Speicherort der Protokolldatei. Am Ende enthält diese Datei die Liste der umbenannten Dateien - zum späteren Nachschlagen.
  4. Rufen Sie an python rename.py.

Warnung: Testen Sie eine kleine Probe, bevor Sie ein ganzes GB Musik riskieren.

Details: Das Umbenennen erfolgt von den innersten Dateien nach außen.

S Prasanth
quelle
0

Mir ist klar, dass dies ein sehr alter Beitrag ist. Die rekursive Lösung von AeroGT80 ist sehr gründlich, aber ziemlich langsam. Ich hatte es ungefähr eine halbe Stunde lang auf einem langsameren Server laufen lassen und es wurde nur ungefähr die Hälfte erledigt - ich denke, es waren ungefähr 73.000 Dateien in ungefähr 300 Unterverzeichnissen.

Die folgende Lösung funktioniert viel schneller (sie verarbeitet alle Dateien in einem Verzeichnis anstelle jeder Datei einzeln - unter Verwendung der nicht rekursiven Lösung von AeroGT80). Das einzige Problem ist, dass es nur ein Verzeichnis tief ist (es ist also nicht vollständig rekursiv wie seine Lösung), aber ich bin sicher, dass es leicht genug geändert werden kann.

#!/bin/bash
for D in *; do
        if [ -d "${D}" ]; then
                #echo "${D}"
                pushd "${D}" > /dev/null
                rename 's|:|-|g' *
                popd > /dev/null
        fi
done
Adam Plocher
quelle