Ich möchte alle Dateien und Verzeichnisse, die das Wort "Spezial" enthalten, in "regulär" umbenennen. Die Groß-/Kleinschreibung sollte beibehalten werden, damit "Spezial" nicht "regelmäßig" wird.
Wie kann ich das in bash rekursiv machen?
Versuchen Sie dies (erfordern bash --version
> = 4):
shopt -s globstar
rename -n 's/special/regular/' **
Entfernen Sie den Schalter -n
, wenn Ihre Tests in Ordnung sind
Es gibt andere Tools mit demselben Namen, die dies möglicherweise nicht können. Seien Sie also vorsichtig.
Wenn Sie den folgenden Befehl ausführen (GNU
)
$ file "$(readlink -f "$(type -p rename)")"
und du hast ein ergebnis wie
.../rename: Perl script, ASCII text executable
und nicht enthaltend:
ELF
dann scheint dies das richtige werkzeug zu sein =)
Wenn nicht, machen Sie es zum Standard (normalerweise bereits der Fall) für Debian
und leiten Sie es wie Ubuntu
ab:
$ Sudo update-alternatives --set rename /path/to/rename
(Ersetzen Sie /path/to/rename
durch den Pfad Ihres Perl's rename
Befehls.
Wenn Sie diesen Befehl nicht haben, durchsuchen Sie Ihren Paketmanager, um ihn zu installieren, oder manuell
Last but not least wurde dieses Tool ursprünglich von Larry Wall, dem Vater von Perl, geschrieben.
Eine Lösung mit find
:
Um nur Dateien umzubenennen :
find /your/target/path/ -type f -exec rename 's/special/regular/' '{}' \;
Um nur Verzeichnisse umzubenennen :
find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \+
Umbenennen von Dateien und Verzeichnissen :
find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+
Wenn Sie nichts dagegen haben, ein anderes Tool zu installieren, können Sie rnm verwenden:
rnm -rs '/special/regular/g' -dp -1 *
Es wird alle Verzeichnisse/Unterverzeichnisse (wegen -dp -1
) durchgehen und special durch regular im Namen ersetzen.
@speakr's answer war der Schlüssel für mich.
Wenn Sie -execdir verwenden, um sowohl Dateien als auch Verzeichnisse zu transformieren, möchten Sie auch -type f
aus dem angezeigten Beispiel entfernen. Um es zu buchstabieren, benutze:
find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+
Erwägen Sie außerdem das Hinzufügen eines g
(global) - Flags zum regulären Ausdruck, wenn Sie all - Vorkommen von special
durch regular
in einem bestimmten Dateinamen und nicht nur beim ersten Vorkommen ersetzen möchten. Zum Beispiel:
find /your/target/path/ -execdir rename 's/special/regular/g' '{}' \+
wandelt special-special.jpg
in regular-regular.jpg
um. Ohne das globale Flag erhalten Sie regular-special.jpg
.
FYI: GNU Umbenennen ist unter Mac OSX nicht standardmäßig installiert. Wenn Sie den Paketmanager Homebrew verwenden, wird brew install rename
Abhilfe schaffen.
Für diejenigen, die nur Verzeichnisse umbenennen möchten, können Sie diesen Befehl verwenden:
find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;
Der Notizentyp ist jetzt d
für das Verzeichnis und verwendet -execdir
.
Ich konnte jedoch nicht herausfinden, wie man Dateien und Verzeichnisse in einem einzigen Durchgang umbenennt.
Jemand hat zuvor kommentiert, dass der Stammordner nicht mehr durchlaufen werden konnte, nachdem er den Stammordner umbenannt hatte. Es steht ein -d
-Schalter zur Verfügung, der von unten nach oben eine Tiefendurchquerung durchführt, so dass der Stamm zuletzt umbenannt wurde, glaube ich:
find -d /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;
Aus der Manpage (man find
):
-d Cause find to perform a depth-first traversal, i.e., directories are visited in post-order and all entries in a directory will be
acted on before the directory itself. By default, find visits directories in pre-order, i.e., before their contents. Note, the
default is not a breadth-first traversal.
Hier ist ein anderer Ansatz, der portabler ist und nicht auf den Befehl rename
angewiesen ist (da er je nach Distros möglicherweise andere Parameter erfordert).
Es benennt Dateien und Verzeichnisse rekursiv um:
find . -depth -name "*special*" | \
while IFS= read -r ent; do mv $ent ${ent%special*}regular${ent##*special}; done
Was es macht
-depth
, um die Ergebnisse mit einem depth-first-Durchlauf neu anzuordnen (d. h. alle Einträge in einem Verzeichnis werden vor dem Verzeichnis selbst angezeigt).Auf diese Weise werden die Dateien zuerst und dann jedes übergeordnete Verzeichnis geändert.
Beispiel
Geben Sie den folgenden Baum:
├── aa-special-aa
│ └── bb-special
│ ├── special-cc
│ ├── special-dd
│ └── Special-ee
└── special-00
Es generiert diese mv
-Befehle in dieser bestimmten Reihenfolge:
mv ./aa-special-aa/bb-special/special-cc ./aa-special-aa/bb-special/regular-cc
mv ./aa-special-aa/bb-special/special-dd ./aa-special-aa/bb-special/regular-dd
mv ./aa-special-aa/bb-special ./aa-special-aa/bb-regular
mv ./aa-special-aa ./aa-regular-aa
mv ./special-00 ./regular-00
Um den folgenden Baum zu erhalten:
├── aa-regular-aa
│ └── bb-regular
│ ├── regular-cc
│ ├── regular-dd
│ └── Special-ee
└── regular-00