#1 Le 15/06/2014, à 17:03
- sylvanux
RESOLU Exercice de Mathieu Nebra (reprenez le controle avec linux)
Bonjour
Voila je suis en train de lire le livre de Mathieu Nebra et je coince sur un exercice qu'il faut faire. C'est un script en shell qui demande à l'utilisateur d'entrer un *.txt après le script et ca renomme tous les fichiers texte avec un "-old".
Si le *.txt n'est pas rentré il faut rentrer les fichiers à renommé.
Voici mon script :
#!/bin/bash
if [ $1 = ".txt" ]; then
for fichier in `ls *.txt`
do
mv $fichier $fichier-old
elif [ -z $1 ]; then
read -p 'Entrez le nom du ou des fichiers à modifier' fichier1 fichier2 fichier3
mv fichier1 fichier1-old
mv fichier2 fichier2-old
mv fichier3 fichier3-old
else
echo 'fin du programe'
fi
Voila quand j'exécute le script j'ai ce message
./essai_variable: ligne 10: Erreur de syntaxe près du symbole inattendu « elif »
./essai_variable: ligne 10: `elif [ -z $1 ]; then'
Je ne sais pas quoi faire.
Sinon j'ai une autre question plus complexe, j'ai entré 3 fichiers a renommé mais comment peut on faire si on ne connait pas le nombre de fichier à l'avance et ainsi entrer un nombre n de variables??
Merci
Dernière modification par sylvanux (Le 17/06/2014, à 19:02)
Hors ligne
#2 Le 15/06/2014, à 17:20
- melixgaro
Re : RESOLU Exercice de Mathieu Nebra (reprenez le controle avec linux)
salut,
déjà cette ligne n'est pas bonne (ça marche, mais c'est pas l'idéal)
for fichier in `ls *.txt`
à remplacer par
for fichier in *.txt
Et il faut fermer la boucle for avec done (c'est ce qui signifie l'erreur : le shell s'attend à trouver done et trouve elif). Donc ça devient
for fichier in *.txt
do
mv -v "${fichier}" "${fichier}-old"
done
Explication :
---------------
- L'expansion de *.txt se fera toute seule et tu n'auras pas de problèmes si des noms de fichiers ont des espaces, contrairement à la ligne que tu as écrite.
- Prendre l'habitude d'écrire les noms de variables avec les accolades. Par exemple, imagine au lieu d'ajouter "-old" tu veux ajouter "1" derrière le nom du fichier. Avec $fichier1, le shell va chercher une variable qui s'appelle fichier1, il ne va pas comprendre que c'est la variable fichier à laquelle il faut ajouter 1 après expansion. Par contre, avec ${fichier}1, il n'y a pas d'ambiguité.
- Prendre l'habitude de mettre des guillemets anglais " autour des variables qui contiennent des chaînes de caractères alphanumériques, en particulier si des espaces risquent d'être présent.
Fais le test en créant un fichier nommé 'nom avec des espaces.txt' et essaye la boucle for avec ta syntaxe et la mienne.
Dernière modification par melixgaro (Le 15/06/2014, à 17:22)
Linux depuis ~2007. Xubuntu seulement.
Hors ligne
#3 Le 15/06/2014, à 20:47
- pingouinux
Re : RESOLU Exercice de Mathieu Nebra (reprenez le controle avec linux)
Bonsoir,
Sinon j'ai une autre question plus complexe, j'ai entré 3 fichiers a renommé mais comment peut on faire si on ne connait pas le nombre de fichier à l'avance et ainsi entrer un nombre n de variables??
En rentrant les fichiers un par un :
while read -p 'Entrez le nom du fichier à modifier : ' fichier
do
[ "$fichier" ] || break
mv "$fichier" "$fichier-old"
done
Hors ligne
#4 Le 17/06/2014, à 17:11
- sylvanux
Re : RESOLU Exercice de Mathieu Nebra (reprenez le controle avec linux)
Voila maintenant je ne vois pas ce qui cloche
#!/bin/bash
if [ $1 = '.txt' ] && [ $# -ge 1 ]
then
for fichier in *.txt
do
mv -v "${fichier}" "${fichier}-old"
done
elif [ -z $1 ]
then
read -p 'Entrez le nom du fichier à modifier : ' fichier
mv "$fichier" "$fichier-old"
else
echo 'fin du programme'
fi
Il m'affiche le message d'erreur suivant :
./essai_variable: ligne 4 : [: = : opérateur unaire attendu
Est-ce que le shell attends une valeur, si je rentre .txt le programme fonctionne, mis à part le message de fin qui ne s'affiche pas??
La réponse doit être toute bête mais n'ayant pas assez d'expérience je vois pas!!!
Hors ligne
#5 Le 17/06/2014, à 17:59
- pingouinux
Re : RESOLU Exercice de Mathieu Nebra (reprenez le controle avec linux)
Comme te l'a indiqué melixgaro en #2, il faut mettre des " " autour des variables quand tu les utilises (utile si elles contiennent des espaces ou sont vides) :
if [ "$1" = '.txt' ] && [ $# -ge 1 ]
............................
elif [ -z "$1" ]
Ton script n'affiche le message de fin que s'il est appelé avec un paramètre non nul et différent de .txt.
Tu pourrais aussi faire ceci :
#!/bin/bash
[ $# = 0 ] && echo 'Donner au moins un nom de fichier'
for fichier in "$@"
do
echo mv -v "${fichier}" "${fichier}-old"
done
echo 'fin du programme'
En appelant le script ainsi :
./le_script *.txt
ou
./le_script fichier1 fichier2
Hors ligne
#6 Le 17/06/2014, à 19:06
- sylvanux
Re : RESOLU Exercice de Mathieu Nebra (reprenez le controle avec linux)
Dis moi à quoi correspond exactement ce symbole : $@ ???
Hors ligne
#7 Le 17/06/2014, à 19:19
- pingouinux
Re : RESOLU Exercice de Mathieu Nebra (reprenez le controle avec linux)
"$@" est remplacé par la liste des paramètres d'appel du script.
Voici un extrait de man bash :
Special Parameters
The shell treats several parameters specially. These parameters may only be referenced; assignment to them is not allowed.
* Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a sin‐
gle word with the value of each parameter separated by the first character of the IFS special variable. That is, "$*" is
equivalent to "$1c$2c...", where c is the first character of the value of the IFS variable. If IFS is unset, the parameters
are separated by spaces. If IFS is null, the parameters are joined without intervening separators.
@ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter
expands to a separate word. That is, "$@" is equivalent to "$1" "$2" ... If the double-quoted expansion occurs within a word,
the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last
parameter is joined with the last part of the original word. When there are no positional parameters, "$@" and $@ expand to
nothing (i.e., they are removed).
Hors ligne