Quelqu'un peut-il recommander une solution sûre pour remplacer récursivement les espaces par des traits de soulignement dans les noms de fichiers et de répertoires à partir d'un répertoire racine donné? Par exemple:
$ tree
.
|-- a dir
| `-- file with spaces.txt
`-- b dir
|-- another file with spaces.txt
`-- yet another file with spaces.pdf
devient:
$ 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
la source
la source
foo bar
et un autre fichier appeléfoo_bar
dans le même répertoire?Réponses:
Utilisez
rename
(akaprename
) qui est un script Perl qui peut déjà être sur votre système. Faites-le en deux étapes:Basé sur la réponse de Jürgen et capable de gérer plusieurs couches de fichiers et de répertoires en une seule liaison en utilisant la version "Revision 1.5 1998/12/18 16:16:31 rmb1" de
/usr/bin/rename
(un script Perl):la source
rename
page de manuel (je ne connaissais pas l'outil) et je pense que vous pouvez optimiser votre code en changeants/ /_/g
eny/ /_/
;-)brew install rename
J'utilise:
Bien que ce ne soit pas récursif, c'est assez rapide et simple. Je suis sûr que quelqu'un ici pourrait le mettre à jour pour être récursif.
La
${f// /_}
partie utilise le mécanisme d'expansion des paramètres de bash pour remplacer un modèle dans un paramètre avec la chaîne fournie. La syntaxe appropriée est${parameter/pattern/string}
. Voir: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html ou http://wiki.bash-hackers.org/syntax/pe .la source
rename
, et c'est trop difficile à installer avec brew ..)for d in *\ *; do mv "$d" "${d// /}"; done
non sous score.shopt -s globstar
etfor f in **/*\ *; do ...
. L'globstar
option est interne à bash, tandis que larename
commande est un outil Linux commun et ne fait pas partie de bash.${f// /_}
est une extension de variable Bash pour la recherche et le remplacement . - Laf
est la variable de lafor
boucle pour chaque fichier qui contient un espace. - Le premier//
signifie "remplacer tout" (ne vous arrêtez pas à la première occurrence). - Ensuite, le `/ _` signifie" remplacer l'espace par un trait de soulignement "n'a pas réussi à le faire correctement au début, parce que je ne pensais pas aux répertoires.
la source
IFS=''
devantread
. En outre, pour ce que je peux dire par d'autres commentaires, l'sort
étape peut être supprimée en faveur de l'-depth
optionfind
.\
(barre oblique inverse). Peut être corrigé en ajoutant une-r
option de lecture.rename
commande suggérée par Dennis.macports
lerename
? Je n'ai jamais pris la peine de le découvrir car je ne pense pas que la tâche justifie l'utilité. Et si vous n'en avez pasmacports
, vous devriez envisager de les installer;)vous pouvez utiliser
detox
par Doug Harplela source
Une solution trouver / renommer . renommer fait partie d'util-linux.
Vous devez d'abord descendre la profondeur, car un nom de fichier d'espaces blancs peut faire partie d'un répertoire d'espaces blancs:
la source
bash 4.0
la source
a' to a subdirectory of itself,
un / a ')/dev/null
.mv
cinquante cinq mille fois seulement pour renommer quatre fichiers peut être un peu surchargé même si vous n'inondez pas l'utilisateur de messages.for file in *' '*
-ce que certains d'entre eux ne feraient pas un meilleur travail?vous pouvez utiliser ceci:
la source
Version récursive des réponses de Naidim.
la source
Voici une solution (assez détaillée) de find -exec qui écrit des avertissements "le fichier existe déjà" dans stderr:
la source
Celui-ci en fait un peu plus. Je l'utilise pour renommer mes torrents téléchargés (pas de caractères spéciaux (non ASCII), d'espaces, de points multiples, etc.).
la source
J'ai trouvé autour de ce script, ça peut être intéressant :)
la source
Voici une solution de script bash de taille raisonnable
la source
ls
.Pour ceux qui ont du mal à utiliser macOS, installez d'abord tous les outils:
Ensuite, lorsque vous devez renommer, créez un alias pour GNU find (gfind) en tant que find. Exécutez ensuite le code de @Michel Krelin:
la source
Cela ne trouve que les fichiers dans le répertoire courant et les renomme . J'ai cette alias.
find ./ -name "* *" -type f -d 1 | perl -ple '$file = $_; $file =~ s/\s+/_/g; rename($_, $file);
la source
Je fais juste un pour mon propre but. Vous pouvez l'utiliser comme référence.
la source
Pour les fichiers du dossier nommé / files
la source
Ma solution au problème est un script bash:
il suffit de mettre le nom du répertoire, sur lequel vous souhaitez appliquer le script, comme argument après avoir exécuté le script.
la source
Tout comme la réponse choisie.
la source