Ich muss ca. umbenennen. 70.000 Dateien. Zum Beispiel: Von sb_606_HBO_DPM_0089000
bis sb_606_dpm_0089000
usw.
Der Nummernkreis reicht von 0089000
bis 0163022
. Es ist nur der erste Teil des Namens, der geändert werden muss. Alle Dateien befinden sich in einem einzigen Verzeichnis und sind fortlaufend nummeriert (eine Bildsequenz). Die Nummern müssen unverändert bleiben.
Wenn ich das in der Bash versuche, wird mir klar, dass die Argumentliste zu lang ist.
Bearbeiten:
Ich habe zuerst versucht, eine einzelne Datei umzubenennen mit mv
:
mv sb_606_HBO_DPM_0089000.dpx sb_606_dpm_0089000.dpx
Dann habe ich versucht, einen Bereich umzubenennen (ich habe letzte Woche hier gelernt, wie man eine Menge Dateien verschiebt, also dachte ich, dass die gleiche Syntax für das Umbenennen der Dateien funktionieren könnte ...). Ich glaube, ich habe Folgendes versucht (oder so ähnlich):
mv sb_606_HBO_DPM_0{089000..163023}.dpx sb_606_dpm_0{089000..163023}.dpx
quelle
ARG_MAX
Limit kollidiert . Da diese Frage ausdrücklich nach einer Befehlszeilenlösung fragt, stimmen (möglicherweise gleiche) GUI-Lösungen wie in der anderen Frage ebenfalls nicht überein.mv {1..2} {3..4}
es nicht funktioniert, was ein ganz anderes Problem ist alsARG_MAX
... Alle anderen, die geantwortet haben, werden wahrscheinlich dasselbe fühlen! Aus meiner Sicht möchte ich, dass Sie Ihre letzte Änderung rückgängig machen und, wenn Sie möchten, eine ganz neue Frage zummv
Umgang mit Bereichen stellenargument list too long
Fehler ist. Es besteht kein Grund zur weiteren Klärung, dies ist eindeutig kein Betrug, da wir eine Problemumgehung für den Umgang mit ARG_MAX benötigen und die Antworten im vorgeschlagenen Duplikat dies nicht tun.Antworten:
Eine Möglichkeit ist die Verwendung
find
mit-exec
und der+
Option. Dadurch wird eine Argumentliste erstellt, die Liste wird jedoch in so viele Aufrufe unterteilt, wie erforderlich sind, um alle Dateien zu verarbeiten, ohne die maximale Argumentliste zu überschreiten. Es ist geeignet, wenn alle Argumente gleich behandelt werden. Dies ist der Fall beirename
, aber nicht beimv
.Möglicherweise müssen Sie Perl umbenennen:
Dann können Sie zum Beispiel verwenden:
Entfernen Sie
-n
nach dem Testen, um die Dateien tatsächlich umzubenennen.quelle
Ich werde drei Alternativen vorschlagen. Jedes ist ein einfacher einzeiliger Befehl, aber ich werde Varianten für kompliziertere Fälle bereitstellen, hauptsächlich für den Fall, dass die zu verarbeitenden Dateien mit anderen Dateien im selben Verzeichnis gemischt werden.
mmv
Ich würde den Befehl mmv aus dem gleichnamigen Paket verwenden :
Beachten Sie, dass die Argumente als Zeichenfolgen übergeben werden, sodass die Glob-Erweiterung nicht in der Shell erfolgt. Der Befehl empfängt genau zwei Argumente und sucht dann intern nach entsprechenden Dateien, ohne die Anzahl der Dateien zu begrenzen. Beachten Sie auch, dass der obige Befehl davon ausgeht, dass alle Dateien, die mit dem ersten Glob übereinstimmen, umbenannt werden sollen. Natürlich steht es Ihnen frei, genauer zu sein:
Wenn Sie Dateien außerhalb des angeforderten Nummernbereichs im selben Verzeichnis haben, ist die Schleife über die weiter unten in dieser Antwort angegebenen Nummern möglicherweise besser für Sie. Sie können jedoch auch eine Folge von mmv-Aufrufen mit geeigneten Mustern verwenden:
Schleife über Zahlen
Wenn Sie vermeiden möchten, etwas zu installieren, oder nach Nummernbereich auswählen möchten, Übereinstimmungen außerhalb dieses Bereichs vermeiden möchten, und bereit sind, auf 74.023 Befehlsaufrufe zu warten, können Sie eine einfache Bash-Schleife verwenden:
Dies funktioniert hier besonders gut, da es keine Lücken in der Sequenz gibt. Andernfalls möchten Sie möglicherweise überprüfen, ob die Quelldatei tatsächlich vorhanden ist.
Beachten Sie, dass im Gegensatz zur
for ((i=89000; i<=163022; ++i))
Klammererweiterung führende Nullen seit einigen Bash-Veröffentlichungen vor einigen Jahren verarbeitet werden. Eigentlich eine Änderung, die ich angefordert habe, also bin ich froh, Anwendungsfälle dafür zu sehen.Weiterführende Literatur: Klammererweiterung auf den Bash-Infoseiten, insbesondere der Teil über
{x..y[..incr]}
.Schleife über Dateien
Eine andere Möglichkeit wäre, eine Schleife über ein geeignetes Glob durchzuführen, anstatt nur über den fraglichen Integer-Bereich zu schleifen. Etwas wie das:
Dies ist wiederum ein
mv
Aufruf pro Datei. Auch hier ist die Schleife über eine lange Liste von Elementen verteilt, aber die gesamte Liste wird nicht als Argument an einen Unterprozess übergeben, sondern intern von bash verarbeitet, sodass das Limit keine Probleme verursacht.Weiterführende Literatur: Shell-Parametererweiterung in den Bash-Infoseiten, dokumentiert
${parameter/pattern/string}
unter anderem.Wenn Sie den Nummernkreis auf den von Ihnen angegebenen einschränken möchten, können Sie dies überprüfen:
Hier
${i##pattern}
wird die längste Präfixübereinstimmungpattern
von entfernt$i
. Dieses längste Präfix ist definiert als alles, dann ein Unterstrich, dann null oder mehr Nullen. Letzteres wird als*(0)
erweitertes Glob-Muster geschrieben , das von der eingestelltenextglob
Option abhängt . Das Entfernen von führenden Nullen ist wichtig, um die Zahl als Basis 10 und nicht als Basis 8 zu behandeln. Das+([0-9])
Argument in der Schleife ist ein weiteres erweitertes Glob, das mit einer oder mehreren Ziffern übereinstimmt, nur für den Fall, dass Sie Dateien haben, die dort gleich beginnen, aber nicht mit a enden Nummer.quelle
Eine Möglichkeit, das
ARG_MAX
Limit zu umgehen, besteht darin, die integrierte Bash-Shell zu verwendenprintf
:Ex.
aber
quelle
find
in aktuellen Verzeichnis.
für alle Dateien-type f
und führen Sie die Datei umbenennen gefunden$1
mit dem ErsetzenHBO_DPM
mitdmp
einer nach dem anderen-exec ... \;
Ersetzen
echo
durchmv
, um die Umbenennung durchzuführen.quelle
Sie könnten ein kleines Python-Skript schreiben, so etwas wie:
Speichern Sie diese Datei als Textdatei
rename.py
in dem Ordner, in dem sich die Dateien befinden. Gehen Sie dann mit dem Terminal in diesem Ordner wie folgt vor:quelle
Sie können es Datei für Datei tun (es kann einige Zeit dauern) mit
Wie das
rename
in anderen Antworten verwendete Perlrename.ul
hat es auch eine Option-n
oder--no-act
zum Testen.quelle
-n
Flag, das ich zum Testen verwendet habe, und schlug vor, dass es auch in verwendetrename.ul
werden kann.Ich sehe, dass niemand meinen besten Freund
sed
zur Party eingeladen hat :). Die folgendefor
Schleife wird Ihr Ziel erreichen:Es gibt viele Tools für einen solchen Job. Wählen Sie das für Sie verständlichste aus. Dieser ist einfach und leicht zu ändern, um diesen oder anderen Zwecken zu entsprechen ...
quelle
$i
in der Befehlsersetzung vermieden werden können , aber keine einfache Möglichkeit ist, eine abschließende Zeile im Dateinamen zu behandeln.Da wir Optionen angeben, folgt ein Perl-Ansatz.
cd
in das Zielverzeichnis und starte:Erläuterung
perl -e
: starte das Skript von-e
.foreach(glob){}
: Führe aus, was auch immer in{ }
jedem Ergebnis des Globus steht.glob("sb_*")
: Gibt eine Liste aller Dateien und Verzeichnisse im aktuellen Verzeichnis zurück, deren Namen mit dem Shell-Glob übereinstimmensb*
.rename $_, s/_HBO_DPM_/_dpm_/r
: Perlmagie.$_
ist eine spezielle Variable, die jedes Element enthält, über das wir iterieren (imforeach
). Hier wird also jede Datei gefunden.s/_HBO_DPM_/_dpm_/
ersetzt das erste Vorkommen von_HBO_DPM_
mit_dpm_
. Es$_
wird standardmäßig mit jedem Dateinamen ausgeführt. Das/r
bedeutet "Diese Ersetzung auf eine Kopie der Zielzeichenfolge (des Dateinamens) anwenden und die geänderte Zeichenfolge zurückgeben. Dasrename
tut, was Sie erwarten: Es benennt Dateien um. Das Ganze wird also den aktuellen Dateinamen ($_
) in sich selbst umbenennen."_HBO_DPM_
ersetzt durch_dpm_
.Sie können dasselbe wie ein erweitertes (und besser lesbares) Skript schreiben:
quelle
Abhängig von der Art der geplanten Umbenennung ist die Verwendung von Vidir mit mehreren Zeilen möglicherweise zufriedenstellend.
In Ihrem speziellen Fall können Sie alle Zeilen in Ihrem Texteditor auswählen und den _ " HBO" -Teil der Dateinamen mit wenigen Tastenanschlägen entfernen .
quelle
vidir
?