Ich habe Dateien und Verzeichnisse, die beginnen mit"Kategorie-Symbol-"in vielen Unterverzeichnissen. Ich versuche, sie rekursiv umzubenennen in"Kategorie-Symbole-". Bitte beachten Sie, dass ich fehlende"G"zumKategorieUnd"S"am Ende vonSymbole.
Ich habe mir jede Menge anderer Fragen zum Umbenennen mehrerer Dateien und Verzeichnisse angesehen, konnte aber keine davon zum Laufen bringen!
Ich wäre für eine kleine Erklärung der Antwort sehr dankbar.
BEARBEITET: Hier ist ein Beispiel meiner Verzeichnisstruktur:
test/cateory-icon-archery/cateory-icon-archery.png
[email protected]
test/cateory-icon-automotive/cateory-icon-automotive.png
[email protected]
Antwort1
Da Sie dies rekursiv tun müssen, find
ist dies das beste Werkzeug. Um den Namen zu ändern, können Sie sh
im -exec
Aufruf verwenden. Hier ist ein Beispiel:
find /some/path -name 'cateory-icon' -exec sh -c 'mv "$1" "${1%/*}/category-icon-${1#cateory-icon-*}"' -- {} \;
Die ${1#cateory-icon-*}
Erweiterung erhält den Dateinamen danach cateory-icon
.
Antwort2
Geben Sie in zsh Folgendes ein .zshrc
(oder führen Sie es einmalig in der Befehlszeile aus):
autoload zmv
alias zcp='zmv -C'
alias zln='zmv -L'
Derzmv
Funktionkombiniert mit zsh'sPlatzhalter und Globbing-Funktionenermöglicht einfaches Umbenennen und Kopieren von Dateien. Hier sind mehrere Möglichkeiten, das gewünschte Ergebnis zu erzielen:
zmv '(**/)cateory-icon-(*)' '${1}category-icons-$2'
zmv -w '**/cateory-icon-*' '${1}category-icons-$2'
zmv '**/cateory-icon-(*)' '$f:h/category-icons-$1'
Erklärung einiger zsh-Funktionen:
**/
gleicht Dateien in Unterverzeichnissen rekursiv ab.- Klammern im Quellausdruck kennzeichnen Gruppen.
$NUM
oder${NUM}
werden im Ersetzungsausdruck durch den Teil des Originalnamens ersetzt, der in der NUM-ten Gruppe enthalten ist. - Klammern
**
sind etwas eigenartig: Sie können sie nur um das Wort herum setzen**/
, nicht mehr und nicht weniger. - Die
-w
Optionzmv
fügt jedes Platzhalterzeichen automatisch einer Gruppe hinzu (bei**
ist dies der**/
Teil, der sich in einer Gruppe befindet, mit dem abschließenden/
). $f
beim Ersetzen ist der vollständige Quelldateiname gemeint.$VAR:h
bedeutet den Verzeichnisteil von$VAR
. Dies ist normalerweise$VAR
bis zum letzten/
, aber alle Randfälle (foo
,foo/
,/
, …) werden korrekt behandelt. Der Basisname ist verfügbar als$VAR:t
.
Antwort3
Verwenden von Perl für maximale Portabilität:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
use File::Copy qw(move);
my $new_name;
finddepth( sub {
if(/cateory-icon/){
($new_name = $File::Find::name) =~ s{.*/\Kcateory-icon}{category-icons};
move $File::Find::name => $new_name;
}
},
'.')
Erläuterung
- Hierbei kommen zwei Perl-Kernmodule zum Einsatz:
File::Find
eines zum rekursiven Durchlaufen von Verzeichnisbäumen undFile::Copy
eines zum rekursiven Kopieren/Verschieben von Verzeichnissen. - Die
finddepth
Funktion (vonFile::Find
) durchläuft die Liste der Verzeichnisse, die als zweites Argument angegeben ist (.
in diesem Fall ist dies das aktuelle Verzeichnis; ändern Sie es nach Bedarf). - Das erste Argument
finddepth
ist eine Subroutinenreferenz, diefinddepth
beim Durchlaufen des Baums für jede angetroffene Datei ausgeführt wird. - Wir starten diese Subroutine mit einer
if
Bedingung: Wenn der übereinstimmende Dateiname das Muster enthält , bilden wir den neuen Namen, indem wir die erforderlichen Korrekturen vornehmen und die Funktion (von )cateory-icon
verwenden, um den aktuellen Namen in den neuen Namen zu ändern.move
File::Copy
Haftungsausschluss
Dieser Code ist ungetestet. Probieren Sie ihn zunächst an einem Dummy-Verzeichnisbaum aus!