Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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

En 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

En 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

En 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 big_smile
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 big_smile

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 tongue) 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 wink


-- 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 roll
Pour les options bash, je ne connaissais pas et je n'aurai pas pensé à regarder le man hmm
En tout cas, merci encore.


-- Lucid Lynx --

Hors ligne