Das Folgende ist eine direkte Lösung Ihres Ansatzes:
find . -type f -name 'file*' -exec sh -c 'x="{}"; mv "$x" "${x}_renamed"' \;
Dies ist jedoch sehr teuer, wenn Sie viele übereinstimmende Dateien haben, da Sie mv
für jede Übereinstimmung eine neue Shell starten (die a ausführt ). Und wenn Sie lustige Zeichen in einem Dateinamen haben, wird dies explodieren. Ein effizienterer und sichererer Ansatz ist der folgende:
find . -type f -name 'file*' -print0 | xargs --null -I{} mv {} {}_renamed
Es hat auch den Vorteil, mit seltsam benannten Dateien zu arbeiten. Wenn es find
unterstützt wird, kann dies auf reduziert werden
find . -type f -name 'file*' -exec mv {} {}_renamed \;
Die xargs
Version ist nützlich, wenn Sie nicht verwenden {}
, wie in
find .... -print0 | xargs --null rm
Hier rm
wird einmalig (oder mit vielen Dateien mehrmals) aufgerufen, aber nicht für jede Datei.
Ich habe die basename
in dir stehende Frage entfernt, weil es wahrscheinlich falsch ist: Du würdest foo/bar/file8
zu file8_renamed
, nicht foo/bar/file8_renamed
.
Bearbeitungen (wie in den Kommentaren vorgeschlagen):
find
Ohne gekürzt hinzugefügtxargs
- Sicherheitsaufkleber hinzugefügt
x
ist das nutzlos:find . -type f -name 'file*' -exec mv {} "{}_renamed" \;
xargs
Version haben die gleiche Effizienz wie das erste Beispiel /x
gibt es nur, um die Ansprache des Fragestellers direkt zu beheben.{}
direkte Verwendung in einem shell (sh -c "…"
) -Befehl ist sehr gefährlich - Sie sollten ihn immer als Argument übergeben. (2) Nicht alle Versionenfind
unterstützen das{}_renamed
Konstrukt. (3) Ich verstehe Ihre Aussage nicht,xargs
die zum Entfernen von Dateien nützlich ist (im Gegensatz zum Umbenennen).xargs
ist nichtmv
vs.rm
, sondern mit{}
vs. ohne. Ersteres ähneltmv file1 file1_renamed; mv file2 file2_renamed
dem letzterenrm file1 file2
.Nachdem ich die erste Antwort ausprobiert und ein wenig damit gespielt hatte, stellte ich fest, dass dies etwas kürzer und weniger komplex sein kann
-execdir
:Sieht so aus, als sollte es auch genau das tun, was Sie brauchen.
quelle
find
Implementierungen, die dies unterstützen-execdir
und{}
nicht als Ganzes, ist dies auch die sicherste. Sie können eine hinzufügen möchten-i
zu ,mv
obwohl (und-T
wenn Ihrmv
unterstützt)mv
eine Eingabeaufforderung zu verlassen, oder zusätzlich dazu können Sie (ohne Zweifel abhängig davon, ob Ihre Implementierung diesfind
unterstützt) auch verwenden,-okdir
welches den auszuführenden Befehl vor der Ausführung ausgibt.-depth
auch eine gute Idee ist, wenn Sie auch Verzeichnisnamen berühren.-execdir
hat eine sehr ärgerliche Kehrseite,find
weigert sich, etwas zu tun, wennPATH
relative Pfade enthält ... askubuntu.com/questions/621132/…find: The relative path XXX is included in the PATH environment
Ein anderer Ansatz ist die Verwendung einer
while read
Schleife über demfind
Ausgang. Dies ermöglicht den Zugriff auf jeden Dateinamen als Variable, die bearbeitet werden kann, ohne sich um zusätzliche Kosten / potenzielle Sicherheitsprobleme beim Erstellen eines separatensh -c
Prozesses mit kümmern zu müssenfind
der-exec
Option von erstellt wird.Und wenn die verwendete Shell die
-d
Option zur Angabe einesread
Begrenzers unterstützt, können Sie Dateien mit seltsamen Namen (z. B. mit einem Zeilenumbruch) folgendermaßen unterstützen:quelle
Ich möchte auf die erste Antwort eingehen und beachten, dass dies beim Anhängen an den Dateinamen nicht funktioniert, da das Pfadpräfix im Dateinamenargument
./
vorhanden ist.Wenn ich die Antwort von Thomas Erker ändere, finde ich, dass dies ein allgemeinerer Ansatz ist
Optionen für xargs:
--null
Gibt an, dass jedes übergebene Argumentstdin
mit einem Nullzeichen (\0
) endet . Auf diese Weise kann der Dateiname Leerzeichen enthalten, andernfalls wird jedes Wort als ein anderer Parameter für die bedrohtmv
Befehl .-I replace-str
Jedes Auftreten vonreplace-str
wird durch das Argument von ersetztstdin
. Sie können es also für eine andere Zeichenfolge ändern, wenn Sie dies benötigen.quelle
pringf "%f\0"
statt aprint0
?-print0
erzeugt./
werden, wenn esPATTERN
Shell-Metazeichen enthält, die beim Umbenennen in etwas stören, das den ursprünglichen Namen vorangestellt ist . (zB umbenennen0 - foo.txt
in00 - foo.txt
,1 - bar.txt
nach01 - bar.txt
usw.)Ich konnte etwas ähnliches mit dem tun
for
,find
undmv
.Dadurch werden alle
config.yml
Dateien gefunden und in umbenanntconfig.yml.bak
quelle
for
einfügen und eine Massenoperation ausführen.