Syntaxe zsh

bonjour,

Je m’attelais à vérifier une boucle, et je dois avouer que je suis assez perplexe…
Ce n’est pourtant pas grand chose.

[code]#!/bin/sh
#script de test

cnt=$(ls -cr ./ | grep .jpg | tr -d ‘[a-z+.]’ | tail -n 1)
i=0
var="“
while [ “$i” -ne “$cnt” ]
do
$i=$(($i+1))
$var=”${var}image${i}.jpg "
echo "i = ${i}"
echo "var = ${var}"
done
echo $var

exit 0[/code]

Ce serait trop demander d’avoir plus simple comme syntaxe ! c’est pourtant pas la mer à boire… Je déteste quand je ne saisis pas les raisons qui poussent à avoir telle forme plutôt qu’une autre… Et là, j’en ai vraiment marre.

Il y a quand même des trucs complêtement con dans la grammaire des scripts shell, des trucs qui ne demandent presque rien pour être amélioré.

J’ai pourtant suivis les quelques tutos accessibles… Je ne sais pas si c’est de ma faute, mais il sont quand même bigrement chiches. pas d’exemple de commande, même pas la syntaxe pour incrémenter un putain d’entier de base !

Bref, à vot’ bon coeur, si quelqu’un se sent d’expliquer en quoi est-ce que ce code est pourris, je lui serais extremement reconnaissant, mais moi là je sature.

J’ai trouvé ça comme infos sur zsh et les boucles[quote=“Stephane Dupille”]
Afficher la citation

Non, ce n'est pas ls qui fait l'erreur, c'est le shell qui fait
l'expansion des *.

Je n’avais pas vu ça, j’y réponds avec un peu de retard :

C’est bien le shell qui effectue l’expension des “*”, mais si rien ne
correspond, il laisse le masque et ne génère pas d’erreur. Je parle du
shell “sh” standard, et des shells compatibles, dans leur configuration
par défaut.

Par exemple :

$ sh

/bin/echo /temp/toto*

/temp/toto*

C’est donc le ls qui indique ne pas trouver le fichier “/temp/toto*”, et
pas sh qui dit ne pas trouver de fichier correspondant à /temp/toto*

Pour le zsh, tu as raison, ce qui prouve que c’est un mauvais shell
qu’il ne faut surtout pas conseiller si on souhaite faire quelque chose
de portable.[/quote]

Ensuite pourquoi n’a tu pas simplement effectuée une boucle for ainsi (*)

for FIC in `ls /temp/toto*|grep -v old 2>>/dev/null` do echo "$FIC" done
Le code ne fonctionne peut-être pas je ne l’ai pas testé

Maintenant se serait sympa si tu commentais un peu ton code histoire de savoir plus facilement ce qu’il fait même si après une lecture on le sait c’est toujours conseillé de commenté son code :wink:

Sinon j’aimerais savoir les tutos que tu as suivi sur la création de boucle en shell car j’en ai trouvé pas mal et qui plus est était assez court niveau syntaxe.

le script plus haut ne sert à rien, c’est juste un bout de code que je serais amené à utiliser bientôt :

au lieu du echo final, je le passe en argument pour ffmpeg, afin de faire de toutes les images d’un dossier particulier un film.

une syntaxe précise existe, mais qui ne fonctionne apparemment pas très bien. Et surtout, que je ne comprends pas du tout. Donc plutôt que de la reprendre, j’écris une routine qui devrait faire la même chose.

En l’occurence, la syntaxe que je souhaites éviter c’est
ffmpeg -f image2 -i image%d.jpg ./film.mpg

car image%d.jpg, même si je sais bien ce que ça doit donner (image1.jpg, image2.jpg), je n’ai aucune info sur son fonctionnement : pas dans la doc ffmpeg, j’en conclus que c’est une syntaxe de shell… Mais là encore, rien n’est précisé, donc je pense que ça viens de bash. Je ne sais pas par exemple si ça peut prendre un nombre illimité, ou plutôt non définis d’image, ou si ça trie correctement les images. Si j’en ai 20 une fois, 300 l’autre, j’aimerais que ça marche quand même. Et là, je ne sais pas si image%03d.jpg fonctionne tout autant pour les 20, etc… Enfin bref :

Pour résumer, je me construit mon argument “manuellement”, pour ne pas avoir de mauvaise surprise, et pour comprendre ce qui se passe. Et parce que je pense que la commande en question ne peut pas fonctionner, ou alors il me manque des bouts de syntaxe et de doc.

là en tout cas, j’ai
./test: 14: 0=1: not found
./test: 14: =image0.jpg : not found
i = 0
./test: 14: 0=1: not found
var =
en sortie.
donc $i=$(($i+1)) ne fonctionne pas… ni $i=‘expr $i + 1’, ni (($i++))…
Et ce qui me frustre, c’est que dans un autre script, j’ai utilisé la syntaxe $i=$(($i+1)), sans aucun problème ! alors là, je ne comprends rien.

Enfin, ce matin ça faisait quelques heures que je travaillais dessus, j’en avais vraiment assez et j’étais fatigué, mais je vais continuer de chercher.

Edit : cette syntaxe semble fonctionner :

[code]#!/bin/zsh
#script de test

cnt=$(ls -cr ./ | grep .jpg | tr -d ‘[a-z+.]’ | tail -n 1)
i=0
var=""
while [ “$i” -ne “$cnt” ]
do
set $i $i+1
set $var "${var}image${i}.jpg "
echo "i = ${i}"
echo "var = ${var}"
done
echo $var

exit 0[/code]

enfin, fonctionner… il n’y a pas d’erreur, ce n’est pas pour autant qu’elle fonctionne. Voici la sortie :
i = 0
var =
i = 0
var =
i = 0
var =
i = 0
var =
i = 0
var =
i = 0
var =

enfin.
si j’écris #!/bin/sh à la première ligne, il faut que j’utilise la syntaxe de sh, non ? pour les questions de compatibilités évoquées plus haut, autant que j’abandonne le zsh pour le script, et que je l’écrive avec une syntaxe courante…

sinon, la syntaxe
ffmpeg -f image2 -i ./image[0-$cnt].jpg ./film.mpg ne pourrait-elle pas avantageusement remplacer toute cette débauche d’efforts ? (où $cnt désignerait le nombre max d’image, et les images ayant été nommées avec une convention qui vas bien…)

J’ai pas compris grand chose de ton problème.

Mais l’incrémentation ça se fait ainsi :

Pas de $ pour les variables parce que sinon le shell les remplace par leur valeur. Imagine que i vale 0 ça donnerais

Sinon tu as ceci en zsh : for (( i=1 ; i < 10 ; i=i+1 )) do echo $i ; done

Sinon a utiliser zsh pourquoi ne pas utiliser zstat (voir man zshmodules) ?

[code]zmodload -F zsh/stat b:zstat

files=(*.jpg)
e=()
zstat +ctime -A e $files[/code]
Après quoi tu auras une correspondances entre le fichier : $file[1] et son ctime : $e[1]. Pour récupérer le fichier max je sais pas s’il y a une méthode pour le faire en une ligne sinon, il faut faire quelque chose de ce genre là :

for (( i=1 ; i < ${#e} ; i=i+1 )) do if [ $e[$i] -gt $e[$max] ]; then max=$i fi done

D’une manière générale le man est ton ami, il te diras énormément de choses.

il faudrait que je prennent des entiers dans une chaîne de caractère, en fait…

ex : image03 --> 3

mais merci pour toutes vos explications, j’y vois beaucoup plus clair désormais.