Renommer des fichiers par lots sous UNIX – dois-je utiliser awk?

J’ai un grand nombre de fichiers image que je dois renommer à partir de la ligne comand. Je crois que la meilleure façon de faire est d’utiliser awk (veuillez corriger si cela est incorrect).

les noms de fichiers sont comme suit

1038282829128738912-1.jpg 

Chaque fichier image commence par “103” et je souhaite remplacer cette partie du nom de fichier par “201003”, laissant le rest intact … par exemple.

 2010038282829128738912-1.jpg 

Les images se trouvent dans plusieurs dossiers sous un dossier principal (images) – mais il serait pratique de copier toutes les images dans un seul dossier (images_renamed)

Je ne sais pas par où commencer – et j’ai googlé pour l’utilisation awk, mais je ne peux trouver que des exemples de renommage du texte à l’ intérieur des fichiers.

Toute aide appréciée. Merci/

Si vous avez la commande rename sur votre UNIX, vous devriez pouvoir utiliser quelque chose comme:

 mkdir images_renamed cd images_renamed cp ../103*.jpg . rename 103 201003 *.jpg 

Le rename FROM TO FILE renommera tous les fichiers spécifiés par FILE , en changeant la première occurrence de FROM en TO .

Si ce n’est pas disponible, vous pouvez utiliser quelque chose comme:

 mkdir images_renamed for fspec in 103*.jpg ; do cp ${fspec} images_renamed/201003${fspec:3} done 

Pour faire cela récursivement, je le mettrais dans un script avec find :

 #!/usr/bin/bash rm -rf images_renamed ls -lR images echo cd images find . -name '*.jpg' | while read -r; do mkdir -p "../images_renamed/$(dirname "$REPLY")" echo 'Copying from' [$REPLY] echo ' to' [../images_renamed/$REPLY] and renaming. echo cp "$REPLY" "../images_renamed/$REPLY" cd "$(dirname "../images_renamed/$REPLY")" rename 103 201003 "$(basename "$REPLY")" cd - >/dev/null done cd .. ls -lR images_renamed 

Seul le niveau intermédiaire est requirejs, le rest est destiné aux tests. Le résultat ci-dessous montre comment cela fonctionne, en copiant tous les fichiers dans la nouvelle structure de répertoires et en renommant les fichiers appropriés.

 images: total 0 drwxr-xr-x+ 1 pax None 0 2010-08-12 20:55 dir1 drwxr-xr-x+ 1 pax None 0 2010-08-12 20:55 dir2 drwxr-xr-x+ 1 pax None 0 2010-08-12 20:56 dir3 images/dir1: total 0 -rw-r--r-- 1 pax None 0 2010-08-12 20:55 102xxx.jpg -rw-r--r-- 1 pax None 0 2010-08-12 20:55 103xxx.jpg images/dir2: total 0 -rw-r--r-- 1 pax None 0 2010-08-12 20:55 103yyy.jpg images/dir3: total 0 drwxr-xr-x+ 1 pax None 0 2010-08-12 20:55 dir 4 images/dir3/dir 4: total 0 -rw-r--r-- 1 pax None 0 2010-08-12 20:55 103zzz.jpg Copying from [./dir1/102xxx.jpg] to [../images_renamed/./dir1/102xxx.jpg] and renaming. Copying from [./dir1/103xxx.jpg] to [../images_renamed/./dir1/103xxx.jpg] and renaming. Copying from [./dir2/103yyy.jpg] to [../images_renamed/./dir2/103yyy.jpg] and renaming. Copying from [./dir3/dir 4/103zzz.jpg] to [../images_renamed/./dir3/dir 4/103zzz.jpg] and renaming. images_renamed: total 0 drwxr-xr-x+ 1 pax None 0 2010-08-12 21:19 dir1 drwxr-xr-x+ 1 pax None 0 2010-08-12 21:19 dir2 drwxr-xr-x+ 1 pax None 0 2010-08-12 21:19 dir3 images_renamed/dir1: total 0 -rw-r--r-- 1 pax None 0 2010-08-12 21:19 102xxx.jpg -rw-r--r-- 1 pax None 0 2010-08-12 21:19 201003xxx.jpg images_renamed/dir2: total 0 -rw-r--r-- 1 pax None 0 2010-08-12 21:19 201003yyy.jpg images_renamed/dir3: total 0 drwxr-xr-x+ 1 pax None 0 2010-08-12 21:19 dir 4 images_renamed/dir3/dir 4: total 0 -rw-r--r-- 1 pax None 0 2010-08-12 21:19 201003zzz.jpg 

Pour aplatir la hiérarchie des fichiers, vous pouvez utiliser quelque chose comme:

 #!/usr/bin/bash rm -rf images_renamed ls -lR images echo cd images mkdir -p ../images_renamed find . -name '*.jpg' | while read -r; do newfile="$(basename "$REPLY")" echo 'Copying from' [$REPLY] echo ' to' [../images_renamed/$newfile] and renaming. echo cp "$REPLY" "../images_renamed/$newfile" cd ../images_renamed rename 103 201003 "$newfile" cd - >/dev/null done 

qui produit:

 cd .. ls -lR images_renamed images: total 0 drwxr-xr-x+ 1 allan None 0 2010-08-12 20:55 dir1 drwxr-xr-x+ 1 allan None 0 2010-08-12 20:55 dir2 drwxr-xr-x+ 1 allan None 0 2010-08-12 20:56 dir3 images/dir1: total 0 -rw-r--r-- 1 allan None 0 2010-08-12 20:55 102xxx.jpg -rw-r--r-- 1 allan None 0 2010-08-12 20:55 103xxx.jpg images/dir2: total 0 -rw-r--r-- 1 allan None 0 2010-08-12 20:55 103yyy.jpg images/dir3: total 0 drwxr-xr-x+ 1 allan None 0 2010-08-12 20:55 dir 4 images/dir3/dir 4: total 0 -rw-r--r-- 1 allan None 0 2010-08-12 20:55 103zzz.jpg Copying from [./dir1/102xxx.jpg] to [../images_renamed/102xxx.jpg] and renaming. Copying from [./dir1/103xxx.jpg] to [../images_renamed/103xxx.jpg] and renaming. Copying from [./dir2/103yyy.jpg] to [../images_renamed/103yyy.jpg] and renaming. Copying from [./dir3/dir 4/103zzz.jpg] to [../images_renamed/103zzz.jpg] and renaming. images_renamed: total 0 -rw-r--r-- 1 allan None 0 2010-08-12 22:41 102xxx.jpg -rw-r--r-- 1 allan None 0 2010-08-12 22:41 201003xxx.jpg -rw-r--r-- 1 allan None 0 2010-08-12 22:41 201003yyy.jpg -rw-r--r-- 1 allan None 0 2010-08-12 22:41 201003zzz.jpg 

mais vous devez garder à l’esprit que les conflits de noms de fichiers (le même nom de fichier sous différents répertoires) se remplaceront l’un l’autre.

En ZSH, vous pouvez le faire (probablement en Bash aussi, pas sûr):

 for f in **/103*.jpg; mv $f some_other_directory/201003${${f:t}#103} 

Peut-être que je peux également vous intéresser à un outil que j’ai écrit: http://github.com/jkramer/virn Il vous permet de renommer en masse des fichiers en utilisant Vim, y compris toutes les fonctionnalités de Vims telles que regex, etc. autre $ EDITOR également).

Quelque chose comme ça pourrait aider:

 cd images find . -name '*.jpg' | while read -r img; do mkdir -p "../images_renamed/$(dirname "$img")" cp -v "$img" "../images_renamed/$(echo "$img" | sed -e 's/^103/201003/')" done 

Note: Non testé. Ne devrait pas supprimer des choses cependant.

Les éléments suivants devraient fonctionner:

 ls -d images* images/ images_renamed/ for i in `find images -type f` do cp $i images_renamed/$(basename $i | sed s/^103/201003/) done 
 find /path -type f -name "10*jpg" | sed 's/.*/mv &/' | sed 's/mv \(.*\/\)\(.[^/]*\)/& \120\2/' | sh 

n’ont pas testé mais quelque chose comme ça pourrait fonctionner en bash:

 for i in `ls 103*.jpg`; do cp $i newdir/201003${i:3}; done