Kann jemand eine sichere Lösung empfehlen, um Leerzeichen rekursiv durch Unterstriche in Datei- und Verzeichnisnamen ab einem bestimmten Stammverzeichnis zu ersetzen? Beispielsweise:
$ tree
.
|-- a dir
| `-- file with spaces.txt
`-- b dir
|-- another file with spaces.txt
`-- yet another file with spaces.pdf
wird:
$ tree
.
|-- a_dir
| `-- file_with_spaces.txt
`-- b_dir
|-- another_file_with_spaces.txt
`-- yet_another_file_with_spaces.pdf
linux
bash
whitespace
filenames
Armandino
quelle
quelle
foo bar
und eine andere Dateifoo_bar
im selben Verzeichnis befinden?Antworten:
Verwenden Sie
rename
(akaprename
), ein Perl-Skript, das sich möglicherweise bereits auf Ihrem System befindet. Machen Sie es in zwei Schritten:Basierend auf Jürgens Antwort und in der Lage mehr Schichten von Dateien und Verzeichnissen in einem einzigen Satz zu handhaben mit der „Revision 1.5 1998.12.18 16.16.31 RMB1“ -Version
/usr/bin/rename
(Perl - Skript):quelle
rename
Manpage gelesen (ich kannte das Tool nicht) und ich denke, Sie können Ihren Code optimieren, indem Sies/ /_/g
zuy/ /_/
;-)brew install rename
Ich benutze:
Obwohl es nicht rekursiv ist, ist es ziemlich schnell und einfach. Ich bin sicher, jemand hier könnte es so aktualisieren, dass es rekursiv ist.
Der
${f// /_}
Teil verwendet den Parametererweiterungsmechanismus von bash, um ein Muster innerhalb eines Parameters durch die angegebene Zeichenfolge zu ersetzen. Die relevante Syntax lautet${parameter/pattern/string}
. Siehe: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html oder http://wiki.bash-hackers.org/syntax/pe .quelle
rename
, und es ist zu schwer, dies mitfor d in *\ *; do mv "$d" "${d// /}"; done
nicht unter Punktzahl verwendet.shopt -s globstar
undfor f in **/*\ *; do ...
. Dieglobstar
Option ist intern für bash, während derrename
Befehl ein allgemeines Linux-Tool ist und nicht Teil von bash.${f// /_}
ist eine Bash-Variablenerweiterung zum Suchen und Ersetzen . - Diesf
ist die Variable aus derfor
Schleife für jede Datei, die ein Leerzeichen enthält. - Das erste//
bedeutet "alle ersetzen" (nicht beim ersten Auftreten aufhören). - Dann bedeutet das "/ _" "Leerzeichen durch Unterstrich ersetzen"Ich habe es zuerst nicht richtig verstanden, weil ich nicht an Verzeichnisse gedacht habe.
quelle
IFS=''
vorread
. Auch für das, was ich durch andere Kommentare sagen kann,sort
kann der Schritt zugunsten der-depth
Option auf fallengelassen werdenfind
.\
(Backslash) enthält. Kann durch Hinzufügen einer-r
Leseoption behoben werden .rename
von Dennis vorgeschlagenen Befehl habe.macports
du das nichtrename
? Ich habe mich nie darum gekümmert, es herauszufinden, weil ich nicht denke, dass die Aufgabe den Nutzen rechtfertigt. Und wenn Sie nicht habenmacports
, sollten Sie in Betracht ziehen, sie zu installieren;)Sie können
detox
von Doug Harple verwendenquelle
Eine Lösung zum Suchen / Umbenennen . Das Umbenennen ist Teil von util-linux.
Sie müssen zuerst die Tiefe verringern, da ein Whitespace-Dateiname Teil eines Whitespace-Verzeichnisses sein kann:
quelle
Bash 4.0
quelle
a' to a subdirectory of itself,
ein / a ' nicht verschieben )/dev/null
.mv
fünfundfünfzigtausend Mal nur zum Umbenennen von vier Dateien erzeugt wird, kann ein wenig Aufwand bedeuten, selbst wenn Sie den Benutzer nicht mit Nachrichten überfluten.for file in *' '*
oder einige solche keinen besseren Job machen?Sie können dies verwenden:
quelle
Rekursive Version von Naidims Antworten.
quelle
Hier ist eine (ziemlich ausführliche) find -exec-Lösung, die Warnungen "Datei existiert bereits" an stderr schreibt:
quelle
Dieser macht ein bisschen mehr. Ich benutze es, um meine heruntergeladenen Torrents umzubenennen (keine Sonderzeichen (Nicht-ASCII), Leerzeichen, mehrere Punkte usw.).
quelle
Ich fand um dieses Skript herum, es kann interessant sein :)
quelle
Hier ist eine Bash-Skriptlösung mit angemessener Größe
quelle
ls
.Installieren Sie zunächst alle Tools, wenn Sie mit macOS Probleme haben:
Erstellen Sie dann bei Bedarf zum Umbenennen einen Alias für GNU find (gfind) als find. Führen Sie dann den Code von @Michel Krelin aus:
quelle
Dadurch werden nur Dateien im aktuellen Verzeichnis gefunden und umbenannt . Ich habe diesen Alias.
find ./ -name "* *" -type f -d 1 | perl -ple '$file = $_; $file =~ s/\s+/_/g; rename($_, $file);
quelle
Ich mache nur eine für meinen eigenen Zweck. Sie können es als Referenz verwenden.
quelle
Für Dateien im Ordner / files
quelle
Meine Lösung für das Problem ist ein Bash-Skript:
Geben Sie einfach den Verzeichnisnamen, auf den Sie das Skript anwenden möchten, als Argument an, nachdem Sie das Skript ausgeführt haben.
quelle
Genau wie die gewählte Antwort.
quelle