#1 Le 31/08/2008, à 08:56
- usky
[resolu] Script bash et espaces dans les noms de fichiers
Hello,
J'ai commencé à écrire un script pour recadrer mes photos en 16/9 pour les voir sur ma TV.
Le but est de lancer le script dans un repertoire et de recadrer toutes les photos du repertoire.
J'ai donc créé une boucle pour recuperer les noms de fichiers dans la variable $filename du type :
#!/bin/bash
for filename in `ls *.JPG`
do
echo "Dropping "$filename"..."
xres=$(identify "$filename" | awk '{print $3}' | awk -F"x" '{print $1}')
yres=$(identify "$filename" | awk '{print $3}' | awk -F"x" '{print $2}')
echo "$filename" x = $xres y = $yres
done
cela marche bien mais ... j'ai des fichiers avec comme premier carractère un espace voir des espaces dans le nom de fichier et là cela se passe beaucoup moins bien ....
Questions :
- Comment gérer ces problèmes d'espace ?
- Est il possible de renomer facilement tous les fichiers du repertoire en photo1.jpg photo2.jpg ...... ?
Dernière modification par usky (Le 02/09/2008, à 20:02)
Un PC Desktop Sous Ubuntu 12.04 Unity + acer1410 sous Unity Plus de windows depuis 2007 Le PC acer est sous Windows7... Ubuntu ne marche plus correctement depuis la 12.04...
http://parrains.linux.free.fr/
Hors ligne
#2 Le 31/08/2008, à 09:14
- HP
Re : [resolu] Script bash et espaces dans les noms de fichiers
pour commencer, c'est une mauvais idée d'utiliser le résultat de ls pour une boucle for… et ça explique (en grande partie) ton souci d'espaces…
cat /dev/urandom >/dev/null 2>&1 #github
Hors ligne
#3 Le 31/08/2008, à 09:17
- geenux
Re : [resolu] Script bash et espaces dans les noms de fichiers
Tu peut utiliser la variable IFS pour définir le caractère de séparation.
IFS="
"
#Ou IFS="\n"
Prendra comme séparateur le retour à la ligne à la place de l'espace.
Ce n'est sans doute pas la meilleure solution, mais elle fonctionne.
Hors ligne
#4 Le 31/08/2008, à 09:42
- usky
Re : [resolu] Script bash et espaces dans les noms de fichiers
Merci geenux je vais regarder
HP, j'en suis à mon 2eme scritp sous nux et je ne connais pas encore toute les subtilitées.
Je me suis basé sur ce que j'ai trouvé ....
Que proposes tu en remplacement de cette methode ?
Un PC Desktop Sous Ubuntu 12.04 Unity + acer1410 sous Unity Plus de windows depuis 2007 Le PC acer est sous Windows7... Ubuntu ne marche plus correctement depuis la 12.04...
http://parrains.linux.free.fr/
Hors ligne
#5 Le 31/08/2008, à 09:47
- geenux
Re : [resolu] Script bash et espaces dans les noms de fichiers
#!/bin/bash
for filename in *.JPG
do
echo "Dropping "$filename"..."
xres=$(identify "$filename" | awk '{print $3}' | awk -F"x" '{print $1}')
yres=$(identify "$filename" | awk '{print $3}' | awk -F"x" '{print $2}')
echo "$filename" x = $xres y = $yres
done
Hors ligne
#6 Le 31/08/2008, à 09:54
- HP
Re : [resolu] Script bash et espaces dans les noms de fichiers
cd $(pwd)
for file in *.jpg; do
echo "$file"
done
pas besoin de ls !
et les quotes "bizarres" ` devraient être remplacés, dans les scripts récents, par la syntaxe utilisée dans la première ligne : Obsolete and deprecated syntax
Après, je veux bien que ce soit ton premier script… mais essaie de lire un peu plus de documentation…
Et c'est valable pour toi, comme pour Geenux, essayez de voir les règles d'échappement des variables et de concaténation… parce que votre utilisation des quotes " est assez étrange…
exemple :
echo "Dropping "$filename"..."
echo "Dropping ${filename}..."
C'est plus joli, non ?
Dernière modification par HP (Le 31/08/2008, à 09:59)
cat /dev/urandom >/dev/null 2>&1 #github
Hors ligne
#7 Le 31/08/2008, à 10:06
- geenux
Re : [resolu] Script bash et espaces dans les noms de fichiers
@HP : Je n'avais pas changé son script, à par pour le ls. J'utilise la bonne syntaxe...
Hors ligne
#8 Le 31/08/2008, à 10:11
- HP
Re : [resolu] Script bash et espaces dans les noms de fichiers
Ok, si tu ne l'a pas changé… mais bon, t'aurais pu, ça blesse les yeux, je trouve, ces quotes qui s'arrêtent et qui reprennent autour des variables…
cat /dev/urandom >/dev/null 2>&1 #github
Hors ligne
#9 Le 31/08/2008, à 14:55
- Alain.g
Re : [resolu] Script bash et espaces dans les noms de fichiers
Ce n'est pas le sujet, mais plutôt que de lancer deux fois identify, associé à awk, il est possible d'utiliser directement l'option -format d'identify :
for img in *.JPG
do
identify -format "%f x = %w y = %h" "$img"
done
Plus d'infos : http://www.imagemagick.org/script/escape.php
Xubuntu Karmic !
Hors ligne
#10 Le 31/08/2008, à 20:21
- usky
Re : [resolu] Script bash et espaces dans les noms de fichiers
HP,
J'ai passé un peu de temps à lire les docs sur differents sites, et c'est la que j'ai copié cette ligne... elle n'est pas de moi
Dans d'autres lignes j'ai d'ailleurs utilisé la syntaxe que tu proposes.
Bon j'ai un truc qui marche :
#!/bin/bash
echo "Attention les fichiers vont etre remplacés. Veuillez confirmer (O/N)"
read ouinon
if [ "$ouinon" = "o" ] || [ "$ouinon" = "O" ]; then
{
for filename in *.jpg
do
xres=$(identify -format "%w" "$filename")
yres=$(identify -format "%h" "$filename")
ycrop=$((yres*3/4))
offset=$((yres/8))
echo $filename x = $xres y = $yres ycrop = $ycrop offset =$offset
res=$(echo $xres'x'$ycrop+0+$offset)
fout=$(echo crop$filename)
if (($xres > $yres)) ; then
{
echo convert "$filename"
convert -crop $res "$filename" "$fout"
}
fi
done
}
elif [ "$ouinon" = "n" ] || [ "$ouinon" = "N" ]; then
{
echo "Ok, bye!"
}
else
{
echo "Il faut taper Y ou N!! Pas" $ouinon
}
fi
exit 0
Merci Alain, cela m'a bien résolu mon probleme d'espace en formatant correctement la sortie de identify, merci HD et geenux pour les explications.
Juste une question subsidiaire : Je voudrais faire une boucle sur *.jpg ET *.JPG, comment on fait ?
PS : et moi qui me demandait à quoi pouvait servir imagemagik il y a peu !! C'est magik
Dernière modification par usky (Le 31/08/2008, à 20:25)
Un PC Desktop Sous Ubuntu 12.04 Unity + acer1410 sous Unity Plus de windows depuis 2007 Le PC acer est sous Windows7... Ubuntu ne marche plus correctement depuis la 12.04...
http://parrains.linux.free.fr/
Hors ligne
#11 Le 31/08/2008, à 21:02
- Totor
Re : [resolu] Script bash et espaces dans les noms de fichiers
for filename in *.[jJ][pP][gG]
mais tu auras aussi JpG comme jpg ou jPG ou ...
sinon, si tu ne souhaites vraiment que jpg ou JPG alors :
ls -1|grep -E '.*\.(jpg|JPG)$'|while read filename
cela dit, il existe un cas "tordu" pour lequel tu auras un pb : un dossier nommé avec une extension .jpg (ou .JPG)
Pour y remédier :
find . -type f -a -iname "\.jpg"|while read filename
tel quel, on se retrouve avec ma première proposition car iname, c'est pour dire : le nom est comme ça en ignorant la case.
Pour avoir exactement jpg ou JPG, j'ai pas de linux sous la main, et je ne sais pas si find connait les expressions régulières étendues (j'ai pas le courage de chercher ) et si ce n'est pas le cas, je ne sais pas comment conjuguer plusieurs conditions 'ET' et 'OU'.
Si find gère les ERE (expressions régulières étendues) :
find . -type f -a -name ".*\.(jpg|JPG)$"|while read filename
si il ne connait pas les ERE, essaie ceci mais je ne suis absolument pas certain de la syntaxe :
find . -type f -a (-name ".*\.jpg$" -o -name ".*\.JPG$")|while read filename
enfin, tu peux conjuguer find et grep pour un résultat certain :
find . -type f|grep -E '.*\.(jpg|JPG)$"|while read filename
PS : Probablement q'Alain aura la solution sans ls ou grep ou find
-- Lucid Lynx --
Hors ligne
#12 Le 31/08/2008, à 21:23
- Alain.g
Re : [resolu] Script bash et espaces dans les noms de fichiers
Pour compléter la réponse de Totor, des solutions en activant certaines options :
Avec l'option nocaseglob, bash effectuera le remplacement (expansion) des noms de fichiers sans tenir compte de la case :
#!/bin/bash
shopt -s nocaseglob
for i in *.jpg
do
echo "image : $i"
done
Avec extglob, on peut utiliser l'opérateur avancé "@()"
#!/bin/bash
shopt -s extglob
for i in *.@(jpg|JPG)
do
echo "image : $i"
done
ou simplement en indiquant *.jpg et *.JPG, mais dans ce cas il vaut mieux activer l'option nullglob, car sinon, sans fichier .JPG, $i serait égal à "*.JPG"
#!/bin/bash
shopt -s nullglob
for i in *.jpg *.JPG
do
echo "image : $i"
done
Les deux derniers exemples afficheront uniquement jpg et JPG, le premier affichera également les JpG jpG etc...
On peut également tout combiner bien-sûr :
#!/bin/bash
shopt -s nocaseglob nullglob extglob dotglob
for i in *.jp@(e|g|eg) *.j?(f)if
do
echo "image : $i"
done
Prendra en compte les extensions jpg, jpe, jpeg, jfif, jif, le tout sans tenir compte de la case et avec les fichiers cachés (grâce à dotglob)
Edit : je n'avais pas fait attention hier aux exemples de Totor concernant find, mais ils ne sont pas tout à fait fait justes :
Le premier recherche les fichiers d'extension jpg sans tenir compte de la case, le second uniquement jpg ou JPG
find -iname "*.jpg"
find \( -name "*.jpg" -o -name "*.JPG" \)
La même en utilisant l'option des expressions rationnelles :
find -iregex ".*\.jpg"
find -regex ".*\.\(jpg\|JPG\)"
(find ne limite pas la recherche au dossier courant, sauf avec l'option adéquate)
Dernière modification par Alain.g (Le 01/09/2008, à 07:03)
Xubuntu Karmic !
Hors ligne
#13 Le 01/09/2008, à 08:54
- Totor
Re : [resolu] Script bash et espaces dans les noms de fichiers
Merci Alain pour ces précisions !
Concernant find, je connaissais les regex et iregex mais je n'y ai pas pensé... et n'ayant pas linux sous les doigts, et ayant la flemme de chercher, je suis passé à côté.
Le coup du *.jpg *.JPG, c'est tout con, mais j'y pense pas
Pour les options bash, je ne connaissais pas et je n'aurai pas pensé à regarder le man
En tout cas, merci encore.
-- Lucid Lynx --
Hors ligne