[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Renommer récursivement



Le 18/09/2010 13:41, Nicolas Roudninski a écrit :
> Bonjour à tous,
> 
> J'imagine que cette question a du être maintes fois soulevée mais j'ai
> beau googeliser, je ne trouve pas de réponse satisfaisante...
> 
> Je dispose d'une grande collection de musique organisée en sous
> répertoires (Artiste/Albums/titre ou Artiste/Albums/disque-n/Titre). Or
> je voudrais remplacer dans tous les répertoires et fichiers, les espaces
> par des underscores.
> J'ai tenté : find /opt/audio -exec rename 's/\s+/_/g' {} \;
> Mais évidemment, ça me répond "/opt/audio/un artiste/un album/ Aucun
> fichier ou répertoire de ce type" vu que le répertoire "un artiste" est
> devenu "un_artiste". J'espère me faire bien comprendre.
> Donc je cherche une commande, un script qui pourrait remplacer tous les
> espaces en underscores en une seule fois.
> 
> Vous auriez ça sous le coude ?
> 
> Cordialement,
> 
> Nicolas Roudninski
> 

Le script que j'ai fais n'est pas forcément le plus simple, mais je
l'avais déjà pour une autre tâche et il s'avère que j'ai pu l'adapter
pour renommer des fichiers. La difficulté en fait c'est de travailler
sur plusieurs dossiers sur plusieurs niveaux tout en les renommant.

Le script travaille avec un dossier temporaire dans lequel seront copiés
les fichiers et dossiers renommé pour ensuite être recopiés dans le
dossier d'origine.

Il faut juste éditer les deux premières variables avec le dossier cible
ainsi qu'un dossier temporaire vide (si possible sur la même partition),
et exécuter le script. Tu peux faire un essai sur un dossier de test
avant comprenant des fichiers avec espaces et d'autres sans, mais j'ai
testé et ça fonctionne bien.


#!/bin/bash

#indiquer le dossier à traiter dans cette variable
dir_from="/home/user/dossier/"
#indiquer un dossier temporaire
tmp_dir="/home/user/dossier_tmp/"


#variable init (ne pas éditer)
array_dir_count1=1
array_dir_count2=0
error=0

dir_array[$array_dir_count2]="$dir_from"
dir_to_array[$array_dir_count2]="$tmp_dir"

if [ "$tmp_dir" != "" ]
  then
ls_tmp_dir=`ls "${dir_to_array[$array_dir_count2]}"`
if [ "$ls_tmp_dir" != "" ]
  then
    echo "Le répertoire temporaire n'est pas vide"
    error=5
fi
else
  echo "pas de répertoire temporaire configuré"
  error=7
fi

if [ ! -w "${dir_to_array[$array_dir_count2]}" ]
  then
    echo "Le répertoire temporaire n'est pas accessible en écriture"
    error=6
fi

until [ "${dir_array[$array_dir_count2]}" == "" ]
  do
  if [ "$error" -eq "0" ]
  then
ls_dir=`ls "${dir_array[$array_dir_count2]}"`
ls_dir=${ls_dir// /@@@@}
for file in $ls_dir
  do
    file_org=${file//@@@@/ }
    file_des=${file//@@@@/_}
    input="${dir_array[$array_dir_count2]}/$file_org"
    output="${dir_to_array[$array_dir_count2]}/$file_des"
    if [ -d "$input" ]
      then
      echo "$input is a directory"
	dir_array[$array_dir_count1]="$input"
	dir_to_array[$array_dir_count1]="$output"
	if [ ! -d "$output" ]
	  then
	    if mkdir "$output"
	      then
		echo "$output created"
	    else
	      error=4
	    fi
	fi
	(( array_dir_count1++ ))
    fi
    if [ -f "$input" ]
      then
	echo "$input is a file"
	if [ -e "$output" ]
	  then
	  output="$output.1"
	fi
	if mv "$input" "$output"
	  then	
	    echo "file $input renemaded as $output"
	else
	  error=1
	fi
    fi
done
#incrémente l'array
(( array_dir_count2++ ))
else
echo "Error $error"
exit $error
fi
done

if [ "$error" -eq "0" ]
  then
    if rm -rf "$dir_from"/*
      then
	if mv "$tmp_dir"/* "$dir_from"/
	  then
	    echo "Done"
	else
	  erro=3
	fi
    else
      error=2
    fi
fi

exit $error

Si jamais tu as dans le même dossier deux fichiers ayant le même nom,
mais un avec des underscores et l'autre avec des espaces, le script en
renommera un avec .1 à la fin (par exemple "piste_01.ogg" et "piste
01.ogg" deviendront "piste_01.ogg" et piste_01.ogg.1", avec les dossiers
par contres, les contenues seront fusionnés (par exemple avec deux
dossiers "The Doors" et "The_Doors"). Le code utilisé pour remplacer les
espaces dans le script est @@@@, change le si tu as des fichiers
contenant quatre arobases dans leur nom (ce qui est peu probable).

Si tu en as la possibilité, fait un backup quand même avant, j'ai bien
testé le script, mais on est pas à l'abri d'une situation d'erreur à
laquelle je n'aurais pas pensé. Et si tu es paranos comme moi et que tu
as l'espace disque suffisant, remplace le mv par un cp à la ligne 71 et
efface ou commente le code entre les lignes 87 et 100 (incluses), tu
auras une copie des fichiers renommés dans le dossier temporaire que tu
pourra vérifier avant d'effacer les autres.

Je joins le script en pièce jointe pour éviter les erreurs de copier coller.

Cordialement

Christophe
#!/bin/bash

#indiquer le dossier à traiter dans cette variable
dir_from="/home/user/dossier/"
#indiquer un dossier temporaire
tmp_dir="/home/user/dossier_tmp/"


#variable init (ne pas éditer)
array_dir_count1=1
array_dir_count2=0
error=0

dir_array[$array_dir_count2]="$dir_from"
dir_to_array[$array_dir_count2]="$tmp_dir"

if [ "$tmp_dir" != "" ]
  then
ls_tmp_dir=`ls "${dir_to_array[$array_dir_count2]}"`
if [ "$ls_tmp_dir" != "" ]
  then
    echo "Le répertoire temporaire n'est pas vide"
    error=5
fi
else
  echo "pas de répertoire temporaire configuré"
  error=7
fi

if [ ! -w "${dir_to_array[$array_dir_count2]}" ]
  then
    echo "Le répertoire temporaire n'est pas accessible en écriture"
    error=6
fi

until [ "${dir_array[$array_dir_count2]}" == "" ]
  do
  if [ "$error" -eq "0" ]
  then
ls_dir=`ls "${dir_array[$array_dir_count2]}"`
ls_dir=${ls_dir// /@@@@}
for file in $ls_dir
  do    
    file_org=${file//@@@@/ }
    file_des=${file//@@@@/_}
    input="${dir_array[$array_dir_count2]}/$file_org"
    output="${dir_to_array[$array_dir_count2]}/$file_des"
    if [ -d "$input" ]
      then
      echo "$input is a directory"
	dir_array[$array_dir_count1]="$input"
	dir_to_array[$array_dir_count1]="$output"
	if [ ! -d "$output" ]
	  then
	    if mkdir "$output"
	      then
		echo "$output created"
	    else
	      error=4
	    fi
	fi
	(( array_dir_count1++ ))
    fi
    if [ -f "$input" ]
      then
	echo "$input is a file"
	if [ -e "$output" ]
	  then
	  output="$output.1"
	fi
	if mv "$input" "$output"
	  then	  
	    echo "file $input renemaded as $output"
	else
	  error=1
	fi 
    fi  
done
#incrémente l'array
(( array_dir_count2++ ))
else
echo "Error $error"
exit $error
fi
done

if [ "$error" -eq "0" ]
  then
    if rm -rf "$dir_from"/*
      then
	if mv "$tmp_dir"/* "$dir_from"/
	  then
	    echo "Done"
	else
	  erro=3
	fi
    else
      error=2
    fi
fi

exit $error

Reply to: