Antworten:
Das rename
Tool, das mit Ubuntu geliefert wird, ist in dieser Hinsicht ziemlich heiß. Sie können kleine Perl-Ausdrücke wie folgt einbetten:
rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *
Das wird dir nur zeigen, was es tun würde. Entfernen Sie die -n
, um es zu einer Live- Feuerübung zu machen.
Dies funktioniert im Wesentlichen, indem eine Variable grob definiert und für jede Datei, die wir treffen, inkrementiert wird. Wenn Sie mehr als 10 Dateien haben, empfehle ich Ihnen, ein Null-Auffüllen in der sprintf
. Folgendes ist gut bis 999
:
rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *
... Aber das lässt sich leicht erweitern.
Um die Antwort von @ Oli zu verbessern , ist in der rename
Tool- Version 1.600 von Aristoteles Pagaltzis tatsächlich ein Zähler eingebaut $N
.
Also alles was du brauchst ist,
rename 's/AS.*/AS$N/' *
Installieren,
brew install rename
oder Laden Sie das Skript herunter/usr/local/bin/brew
oder /usr/bin
)rename
können Sie direkt zuweisen $_
, die für dieses Problem ideal ist.Obwohl die an das Perl- rename
Dienstprogramm übergebenen Codeargumente häufig einen Abgleich und eine Substitution (mit s/
) durchführen und es durchaus akzeptabel ist , dieses Problem auf diese Weise zu lösen, ist dies in Fällen wie diesem, in denen Sie oder nicht wirklich untersuchen, wirklich nicht erforderlich Wiederverwenden des Textes der alten Dateinamen. rename
lässt Sie so gut wie jeden Perl-Code schreiben , und er muss nicht in ihn eingebettet sein s/
/e
. Ich schlage vor, einen Befehl wie diesen zu verwenden:
rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *
Oder, wenn Sie Lust haben, ein paar Charaktere abzuschaben:
rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *
(Es könnte noch kürzer gemacht werden, aber nicht ohne Einbußen bei der Klarheit.)
Beide Befehle machen dasselbe. Jedes zeigt, welche Umbenennungsoperationen durchgeführt würden. Sobald Sie eine ausprobiert haben und mit den Ergebnissen zufrieden sind, führen Sie sie ohne die -n
Option erneut aus. Wie schon geschrieben, würde dies die Dateinamen produzieren AS01.txt
, AS02.txt
, ..., AS10.txt
, AS11.txt
, und so weiter. Sie können sie nach Bedarf ändern und erst dann entfernen, -n
wenn Sie das sehen, was Sie sehen.
Wenn Sie eine größere Breite als 2 auffüllen möchten, ersetzen Sie die 2
durch eine größere Zahl. Wenn aus irgendeinem Grund Sie zum Beispiel Dateinamen gesucht möchten AS00000000000001.txt
, würden Sie ersetzen %02d
mit %014d
. Wenn Sie überhaupt kein Auffüllen möchten - auch wenn dadurch Ihre Dateien in nicht numerischer Reihenfolge angezeigt werden, wenn Sie sie später auflisten! -, können Sie sie durch %02d
just ersetzen %d
.
Wie funktioniert das? Ihre Shell wird *
zu einer Liste von Dateien erweitert, noch bevor der rename
Befehl ausgeführt wird. Die Liste ist lexikografisch (dh alphabetisch) nach Ihren aktuellen Ländereinstellungen sortiert. rename
empfängt die Dateinamen als Befehlszeilenargumente und verarbeitet sie in der angegebenen Reihenfolge. Der Ausdruck wird ++$i
mit einem Wert bewertet, der größer ist als der aktuelle Wert der Variablen $i
, und die Variable wird auch $i
auf diesen neu inkrementierten Wert gesetzt. Dieser Wert wird an übergeben sprintf
, der ihn formatiert und in anderen Text einfügt. Dieser Text wird direkt der speziellen Variablen zugewiesen $_
, die den Dateinamen enthält. Da die rename
Dateien in der Reihenfolge verarbeitet werden, in der sie als Argumente übergeben werden, werden sie entsprechend nummeriert.
Beide deklarieren und erhöhen eine Zählervariable und beide verwenden sprintf
im Wesentlichen dieselbe Methode, um den Wert dieses Zählers, der links mit Nullen aufgefüllt ist, in den anderen Text der neuen Dateinamen einzubetten. (Die Informationen in einer der Antworten zum Auffüllen mit Nullen - und zum Ändern der Auffüllbreite - gelten auch für beide gleichermaßen.) Der Grund für die Ähnlichkeit ist, dass die Methode in dieser älteren Antwort tatsächlich nur diese 1 ausführt , aber mit zusätzlichen Schritten, die für viele Probleme nützlich sind, aber für dieses nicht wirklich notwendig sind.
Zum Vergleich: So sieht der zweite Befehl in dieser Antwort aus, wenn er geändert wurde, um den hier verwendeten Stil zu verwenden (und statt 3 auf eine Breite von 2 zu füllen, wie ich es hier getan habe):
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *
Der Teil zwischen s/.+/
und /e
in diesem Befehl ist jetzt der gleiche wie der Ausdruck, den ich im ersten Befehl in dieser Antwort zugewiesen habe $_
(dh der Code auf der rechten Seite des =
Operators).
s/
Operator versucht, Text (Dateinamen, die von Ihrer Shell erweitert *
und bei der Ausführung als Befehlszeilenargumente übergeben wurden rename
) mit einem regulären Ausdruck abzugleichen und führt eine Ersetzung durch. /
wird als Trennzeichen verwendet, um die verschiedenen Teile des s
Ausdrucks zu trennen . Der erste Teil .+
ist der reguläre Ausdruck; sie paßt jede 1 - Zeichen ( .
) , und zwar eine oder mehr Male ( +
) . Da Dateinamen nie leer sind - sie sind immer mindestens ein Zeichen lang - das ist ein Weg , um alle passen 1 Dateinamen.our $i; sprintf "AS%02d.txt", ++$i
. Dies erzeugt den neuen Dateinamen. In der Regel wird s/
Text erzeugt, der entweder (a) Text ersetzt, der nur einem Teil des Dateinamens entspricht, oder (b) auf der Grundlage des übereinstimmenden Texts in irgendeiner Weise erstellt wird (z. B. wird möglicherweise eine solche spezielle Variable verwendet $&
, die zu erweitert wird das Match). In diesem Fall wird der übereinstimmende Text jedoch überhaupt nicht verwendet.our $i; sprintf "AS%02d.txt", ++$i
als Dateiname verwendet und nicht als Code ausgeführt. Das /e
Flag am Ende bewirkt jedoch, dass dieser Text als Perl-Quellcode behandelt und ausgewertet wird, und verwendet den dabei erzeugten Wert (in diesem Fall den Rückgabewert der integrierten Perl- sprintf
Funktion) als neuen Dateinamen.Obwohl ich denke , die Methode , die ich hier gezeigt habe ein klarer und einfacher Ansatz ist für dieses Problem als jede Methode , dass Anwendungen s/
mit /e
, ist es gut , diese Technik bewusst zu sein, denn es ist gut zu einer Reihe von anderer Datei umbenennen Problemen geeignet ist , wo alle oder ein Teil der ursprünglichen Dateinamen wird geprüft und / oder beibehalten. Ich empfehle diesen Blog-Beitrag von Oli (der auch diese Antwort geschrieben hat ), der einige solcher Beispiele enthält.
1 Technisch gesehen gibt es einen Unterschied im Verhalten der $_ =
Befehle und der s/
/e
Befehle. Im regulären Ausdruck .+
ist es nicht unbedingt wahr, dass es .
mit einem Zeichen übereinstimmt , da es nicht mit einer Newline übereinstimmt . Sie sollten höchstwahrscheinlich keine Dateinamen mit Zeilenumbrüchen verwenden, aber Sie können, und gelegentlich wird eine Datei versehentlich so benannt. Wenn Sie Lust dazu haben, kontrastieren Sie die Ausgabe von rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'
mit der von rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'
. .
Verwenden Sie die Markierung s
am Ende (mit e
) , um eine neue Zeile abzugleichen . Das heißt, schreiben Sie /se
am Ende statt /e
.
Angenommen, die Dateien, die Sie umbenennen möchten, befinden sich in ~/Adir
und dies sind die einzigen Dateien in diesem Ordner.
n=0
for f in $( ls ~/Adir | sort ) ; do
n=$(( n+1 ))
mv -n "$f" "AS${n}.txt"
done
Dieses Skript überprüft jede Datei in ~/Adir
und benennt sie in um, AS1.txt, AS2.txt, ...
wenn die Datei nicht vorhanden ist (es wird nicht überschrieben). Deshalb sollten Sie sicherstellen, dass dies die einzigen Dateien in sind ~/Adir
. Der sort
Befehl ist nur für den Fall, dass die Dateien die ursprüngliche Reihenfolge beibehalten sollen.
rename
ist der Vorname. Dies ist möglicherweise besser, aber Sie möchten möglicherweise Installationsanweisungen hinzufügen, um diese Antwort wertvoller zu machen.