Comment renommer des fichiers avec des espaces à l'aide du shell Linux?

28

J'ai nommé un certain nombre de fichiers contenant des espaces et je souhaite remplacer l'espace par _. Cependant, chaque fois que j'écris une commande dans le shell avec le nom de fichier (par exemple Spring 2011), le shell ne reconnaît pas le fichier ou le répertoire.

Que puis-je faire à ce sujet? Existe-t-il un moyen d'utiliser le caractère unicode pour un espace?

Phil Braun
la source
pour renommer par programme N fichiers, utilisez une bashboucle for: voir ma solution ici .
Trevor Boyd Smith

Réponses:

33

Échapper à l'espace, par exemple Spring\ 2011, ou utiliser des guillemets, par exemple 'Spring 2011'. À l'avenir, c'est généralement une mauvaise idée d'utiliser des noms de fichiers avec des espaces sur n'importe quel * NIX.

Si vous en avez rename, vous pouvez utiliser ceci:

rename ' ' '_' [filenames...]
Rafe Kettler
la source
1
Savez-vous qu'il est possible de le faire pour tous les fichiers à la fois?
3
Pourquoi est-ce une mauvaise idée? Il incombe au programmeur de gérer correctement les noms de fichiers.
glenn jackman
1
@rafe, il est vraiment sujet aux erreurs de ne pas gérer correctement les noms de fichiers à l'avance. L'effort supplémentaire vient lorsque vous devez déboguer un script lorsque vous avez simplement oublié de citer des variables contenant un nom de fichier.
glenn jackman
3
Cette réponse ne semble pas fonctionner (sur Ubuntu 12.04 LTS, au moins). La réponse de unutbu fonctionne bien cependant.
DNA
1
cela n'a fait que le premier espace pour moi ... ce qui n'est pas utile (j'ai la renameversion 2.23)
Trevor Boyd Smith
30

Si votre machine a la commande rename , cela changera tous les espaces en soulignés dans tous les fichiers / répertoires du répertoire de travail actuel:

rename 's/ /_/g' *
unutbu
la source
Confirmé de travailler dans Ubuntu 12.04
anthonygore
1
n'a pas fonctionné pour moi ... j'ai eu une erreur de "renommer: pas assez d'arguments". j'ai la version rename --version rename from util-linux 2.23.2.
Trevor Boyd Smith
-bash: /usr/bin/rename: Argument list too long
nmz787
24

Si vous n'avez pas renameou préférez utiliser uniquement le shell:

for f in *\ *; do mv "$f" "${f// /_}"; done

En panne:

  • *\ *sélectionne tous les fichiers avec un espace dans leur nom comme entrée pour la forboucle.
  • Les guillemets autour "$f"sont importants car nous savons qu'il y a un espace dans le nom de fichier et sinon il apparaîtrait comme 2+ arguments pour mv.
  • ${f//str/new_str}est une fonction de substitution de chaîne spécifique à bash. Toutes les instances de strsont remplacées par new_str.
blahdiblah
la source
2
cela fonctionne mais pour moi, il ne remplace que le premier espace. si j'utilise for f in *\ *; do mv "$f" "${f// /_}"; doneça marche
billynoah
@billynoah Bonne capture, mise à jour.
blahdiblah
@blahdiblah Merci beaucoup! Tu m'as sauvé tellement de temps!
Guerrilla
@blahdiblah votre solution est bien plus élégante que ma solution . bon travail. Je ne pensais pas que le glob de boucle for fonctionnerait ... alors j'ai fait le glob en dehors de la boucle for.
Trevor Boyd Smith
3

mv "Spring 2011.file" Spring_2011.file devrait indiquer à la ligne de commande de prendre la chaîne entre guillemets comme une seule entrée.

rockerest
la source
C'est la seule réponse que j'ai pu obtenir pour travailler.
blakeoft du
1

Pour renommer par programme N fichiers, vous pouvez utiliser une bashboucle for simple .

#!/bin/bash

set -eux

# find all your files by using a `grep` pattern
pattern="insert_filename_pattern_here" # you must enter your filename pattern here

# create an array of filenames and split on newlines
IFS=$'\n'
tmp=($(ls | grep ${pattern}))
unset IFS

# for each filename
for filename in "${tmp[@]}"; do
    # rename the filename to use "_" character instead of a " " character
    mv -v "${filename}" "${filename// /_}"
done

Si vous avez moins de 5 noms de fichiers, vous pouvez saisir manuellement tous les noms de fichiers et utiliser la renamecommande comme le suggère la solution ci-dessus . Mais pour moi ... je préfère la solution programmatique ... même quand il n'y a que 4 fichiers.

ps

si vous n'êtes pas familier avec Bashl'extension des paramètres (c'est-à-dire ${filename// /_}), vous pouvez utiliser la renamecommande:

if ((0)); then
    mv -v "${filename}" "${filename// /_}"
else
    rename ' ' '_' "${filename}"
fi
Trevor Boyd Smith
la source