web-dev-qa-db-fra.com

Évitez de remplacer les espaces lorsque vous renommez des fichiers

J'essaie de renommer des fichiers comme ceci:

for file in *;
do
mv -i "$file" "$(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')";
done

Mais la commande sed remplace tous les espaces par _.

Comment puis-je modifier la commande sed pour l'inclure des espaces avec les caractères spécifiés? J'ai essayé d'utiliser \s mais cela ne fonctionne pas ...

MODIFIER:
Par exemple: le fichier trip: hill doit être renommé: trip_ hill, mais la commande ci-dessus le rend trip__hill.

10
user679568

Ne pas analyser les noms de fichiers avec sed! La sortie de echo "$file" peut ne pas être fiable.

Utilisez rename. Le 17.10, vous devez d'abord l'installer

Sudo apt install rename

Ensuite:

rename -n -- 's/[^-A-Za-z0-9_ .]/_/g' *

Remarques

  • remove -n après le test pour renommer les fichiers
  • -- fin d'options au cas où un fichier commence par -
  • [^-A-Za-z0-9_ .] caractères que nous ne souhaitons pas remplacer - mettez - en premier ou en dernier afin qu'il ne puisse pas indiquer de plage (il est traité littéralement dans ces positions).
  • Les espaces peuvent être inclus dans la classe
  • .est traité littéralement (dans d'autres contextes regex, il représente n'importe quel caractère et doit être échappé).

Cela fonctionne aussi dans sed:

$ echo 'trip: hill' | sed 's/[^-A-Za-z0-9 _.]/_/g'
trip_ hill

Si j'ajoute un espace à la fin de votre version, j'obtiens une erreur:

$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._- ]/_/g'
sed: -e expression #1, char 22: Invalid range end

Mais avec - à la fin, cela fonctionne:

$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._ -]/_/g'
trip_ hill

Alors peut-être que la position du trait d'union a causé votre problème lorsque vous avez ajouté l'espace. Mais le conseil de ne pas analyser les noms de fichiers est valable!

11
Zanna

Vous pouvez également simplement utiliser le shell, expansion des paramètres de Bash peut effectuer une substitution:

for f in ./* ; do
    mv "$f" "${f//[^-A-Za-z0-9._ ]/_}"
done

La double barre oblique lui dit de remplacer toutes les correspondances, à part cela, la syntaxe est simple.

2
ilkkachu