Antworten:
Ein portabler Weg (der auf jedem POSIX-kompatiblen System funktioniert):
find /the/path -depth -name "*.abc" -exec sh -c 'mv "$1" "${1%.abc}.edefg"' _ {} \;
In bash4 können Sie globstar verwenden, um rekursive Globs zu erhalten (**):
shopt -s globstar
for file in /the/path/**/*.abc; do
mv "$file" "${file%.abc}.edefg"
done
Der (Perl) rename-Befehl in Ubuntu kann Dateien mithilfe der Perl-Syntax für reguläre Ausdrücke umbenennen, die Sie mit globstar kombinieren können, oder find:
# Using globstar
shopt -s globstar
files=(/the/path/**/*.abc)
# Best to process the files in chunks to avoid exceeding the maximum argument
# length. 100 at a time is probably good enough.
# See http://mywiki.wooledge.org/BashFAQ/095
for ((i = 0; i < ${#files[@]}; i += 100)); do
rename 's/\.abc$/.edefg/' "${files[@]:i:100}"
done
# Using find:
find /the/path -depth -name "*.abc" -exec rename 's/\.abc$/.edefg/' {} +
Siehe auch http://mywiki.wooledge.org/BashFAQ/030
"${1%.abc}"erweitert sich am Ende auf den Wert von $1except without .abc. Weitere Informationen zu Shell-String-Manipulationen finden Sie in FAQ 100 .
${1%.abc}...
sh -c dem ersten Argument $ 0 zugewiesen wird und alle verbleibenden Argumente den Positionsparametern zugewiesen werden . Das _ist also ein Scheinargument, und '{}' ist das erste Positionsargument für sh -c.
Dies erledigt die erforderliche Aufgabe, wenn sich alle Dateien in demselben Ordner befinden
rename 's/.abc$/.edefg/' *.abc
So benennen Sie die Dateien rekursiv um:
find /path/to/root/folder -type f -name '*.abc' -print0 | xargs -0 rename 's/.abc$/.edefg/'
rename 's/.abc$/.edefg/' /path/to/root/folder/**/*.abcin einer modernen Version von Bash.
sam Anfang und welche anderen Optionen kann ich dort verwenden. Vielen Dank !
Ein Problem bei rekursiven Umbenennungen besteht darin, dass unabhängig von der Methode, mit der Sie die Dateien suchen, der gesamte Pfad renameund nicht nur der Dateiname übergeben wird. Das macht es schwierig, komplexe Umbenennungen in verschachtelten Ordnern vorzunehmen.
Ich benutze finddie -execdirAktion, um dieses Problem zu lösen. Wenn Sie -execdiranstelle von verwenden -exec, wird der angegebene Befehl aus dem Unterverzeichnis ausgeführt, das die übereinstimmende Datei enthält. Anstatt den gesamten Pfad dahin zu führen rename, geht er nur vorbei ./filename. Das macht es viel einfacher, den regulären Ausdruck zu schreiben.
find /the/path -type f \
-name '*.abc' \
-execdir rename 's/\.\/(.+)\.abc$/version1_$1.abc/' '{}' \;
Im Detail:
-type f bedeutet nur nach Dateien suchen, nicht nach Verzeichnissen-name '*.abc' bedeutet, dass nur Dateinamen gefunden werden, die auf .abc enden'{}'ist der Platzhalter, der die Stelle markiert, an der -execdirder gefundene Pfad eingefügt wird. Die einfachen Anführungszeichen sind erforderlich, damit Dateinamen mit Leerzeichen und Shell-Zeichen behandelt werden können.-typeund -namesind das Bash-Zeilenfortsetzungszeichen. Ich verwende sie, um dieses Beispiel besser lesbar zu machen, aber sie werden nicht benötigt, wenn Sie Ihren Befehl in eine einzige Zeile schreiben.-execdirZeile ist jedoch erforderlich. Es ist dazu da, das Semikolon zu verlassen, das den von ausgeführten Befehl beendet -execdir. Spaß!Erklärung des regulären Ausdrucks:
s/ Beginn der Regex\.\/stimmen Sie mit der führenden ./ überein, die -execdir eingibt. Verwenden Sie \, um die. und / oder Metazeichen (Hinweis: Dieser Teil variiert je nach Ihrer Version von find. Siehe Kommentar von Benutzer @apollo)(.+)stimmen mit dem Dateinamen überein. Die Klammern erfassen die Übereinstimmung für die spätere Verwendung\.abc Entkomme dem Punkt und passe das ABC an$ Verankern Sie die Übereinstimmung am Ende der Zeichenfolge
/ markiert das Ende des "Match" -Teils des regulären Ausdrucks und den Beginn des "Ersetzen" -Teils
version1_ Fügen Sie diesen Text jedem Dateinamen hinzu
$1verweist auf den vorhandenen Dateinamen, da dieser in Klammern angegeben ist. Wenn Sie im Teil "Übereinstimmung" mehrere Sätze von Klammern verwenden, können Sie hier mit $ 2, $ 3 usw. darauf verweisen..abcDer neue Dateiname endet mit .abc. Das Punkt-Metazeichen muss hier im Abschnitt "Ersetzen" nicht entfernt werden/ Ende der RegexVor
tree --charset=ascii
|-- a_file.abc
|-- Another.abc
|-- Not_this.def
`-- dir1
`-- nested_file.abc
Nach
tree --charset=ascii
|-- version1_a_file.abc
|-- version1_Another.abc
|-- Not_this.def
`-- dir1
`-- version1_nested_file.abc
Hinweis: renameDie Option -n ist nützlich. Es führt einen Trockenlauf durch und zeigt Ihnen, welche Namen es ändern wird, nimmt jedoch keine Änderungen vor.
--execdirnicht in der Führung vorbeigekommen , ./so dass der \.\/Teil in der Regex weggelassen werden kann. Mai das ist, weil ich auf OSX nicht Ubuntu
Ein weiterer portabler Weg:
find /the/path -depth -type f -name "*.abc" -exec sh -c 'mv -- "$1" "$(dirname "$1")/$(basename "$1" .abc).edefg"' _ '{}' \;
# Rename all *.txt to *.text
for f in *.txt; do
mv -- "$f" "${f%.txt}.text"
done
Lesen Sie auch den Eintrag, warum Sie nicht analysieren sollten ls.
Bearbeiten: Wenn Sie den Basisnamen verwenden müssen, lautet Ihre Syntax:
for f in *.txt; do
mv -- "$f" "$(basename "$f" .txt).text"
done
https://unix.stackexchange.com/questions/19654/changing-extension-to-multiple-files
Dies ist, was ich getan und ziemlich genau so gearbeitet habe, wie ich es wollte. Ich habe den mvBefehl verwendet. Ich hatte mehrere .3gpDateien und wollte sie alle in umbenennen.mp4
Hier ist ein kurzer Oneliner dafür:
for i in *.3gp; do mv -- "$i" "ren-$i.mp4"; done
Der durchsucht einfach das aktuelle Verzeichnis, nimmt alle .3gp-Dateien auf und benennt sie dann (mit dem MV) in um ren-name_of_file.mp4
file.3gpzu file.3gp.mp4, was vielleicht nicht , was die meisten Leute wollen.
.3gpoder .mp4hier waren nur zu Illustrationszwecken.
basename "$i" .mp4, um die vorherige Erweiterung anstelle von "ren- $ i.mp4" zu entfernen.
Ich würde den Befehl mmv aus dem gleichnamigen Paket verwenden :
mmv ';*.abc' '#1#2.edefg'
Die ;entspricht null oder mehr */und entspricht #1in der Ersetzung. Das *entspricht #2. Die nicht-rekursive Version wäre
mmv '*.abc' '#1.edefg'
Benennen Sie Dateien und Verzeichnisse mit find -execdir | rename
Wenn Sie Dateien und Verzeichnisse nicht einfach mit einem Suffix umbenennen, ist dies ein gutes Muster:
PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
find . -depth -execdir rename 's/findme/replaceme/' '{}' \;
Anders -execdirals cdbei der Option " awesome " wird vor dem Ausführen des renameBefehls ein Eintrag in das Verzeichnis erstellt -exec.
-depth Stellen Sie sicher, dass die Umbenennung zuerst bei Kindern und dann bei Eltern erfolgt, um potenzielle Probleme mit fehlenden Elternverzeichnissen zu vermeiden.
-execdir ist erforderlich, weil das Umbenennen bei Eingabepfaden ohne Basisnamen nicht gut funktioniert, z. B. schlägt Folgendes fehl:
rename 's/findme/replaceme/g' acc/acc
Das PATHHacken ist erforderlich, da -execdires einen sehr ärgerlichen Nachteil hat: Es findist äußerst kritisch und weigert sich, irgendetwas damit zu tun, -execdirwenn Sie relative Pfade in Ihrer PATHUmgebungsvariablen haben, z ./node_modules/.bin.
find: Der relative Pfad './node_modules/.bin' ist in der Umgebungsvariablen PATH enthalten, die in Kombination mit der Aktion -execdir von find unsicher ist. Bitte entfernen Sie diesen Eintrag aus $ PATH
Siehe auch: Warum ist die Verwendung der Aktion '-execdir' für Verzeichnisse im PATH unsicher?
-execdirist eine GNU find Erweiterung zu POSIX . renameist Perl-basiert und stammt aus dem renamePaket. Getestet in Ubuntu 18.10.
Benennen Sie die Lookahead-Problemumgehung um
Wenn Ihre Eingabepfade nicht von stammen findoder wenn Sie genug von der relativen Pfadbelästigung haben, können wir einige Perl-Lookaheads verwenden, um Verzeichnisse sicher umzubenennen, wie in:
git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'
Ich habe nicht eine bequeme analog gefunden -execdirmit xargs: https://superuser.com/questions/893890/xargs-change-working-directory-to-file-path-before-executing/915686
Das sort -rist erforderlich, um sicherzustellen, dass Dateien nach ihren jeweiligen Verzeichnissen kommen, da längere Pfade nach kürzeren mit demselben Präfix kommen.