Script sh

Discutez d'informatique ici !
Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

Script sh

par Rockleader » 10 Nov 2013, 14:12

Bonjour; bonsoir

J'ai quelques soucis pour réaliser un script en sh de traduction à partir des données suivantes.

On a un fichier f1.txt sous cette forme là

Night is dark
and full of terror


On a un fichier f2.txt
is est
and et
Night Dark
etc etc pas d'ordre précis; il y a le mot anglais suivi de sa traduction


Le but est donc de créer le texte en français dans un fichier f3.

Il s'agit d'un exo de tp que je n'ai pas réussi à terminer; je viens donc vous demander conseil sur la façon de faire.

Merci à vous.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !



Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 10 Nov 2013, 14:38

slt,

dans les grandes lignes.
Code: Tout sélectionner
pour chaque ligne de f1.txt as line
 pour chaque mot de line as word
  #recupere la translation
  translatedWord=$(grep mot f2.txt |cut -d' ' -f2)
 finpour
finpour

pour chaque ligne de f1.txt, c'est trivial
pour chaque mot de line, tu peux t en sortir en changeant l IFS (par exemple mettre un IFS=' ') ou bien tu remplaces lespace par un \n puis tu ouput la ligne dans un fichier. Et apres tu grep chaque ligne du fichier temporaire
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 10 Nov 2013, 15:28

fatal_error a écrit:slt,

dans les grandes lignes.
Code: Tout sélectionner
pour chaque ligne de f1.txt as line
 pour chaque mot de line as word
  #recupere la translation
  translatedWord=$(grep mot f2.txt |cut -d' ' -f2)
 finpour
finpour

pour chaque ligne de f1.txt, c'est trivial
pour chaque mot de line, tu peux t en sortir en changeant l IFS (par exemple mettre un IFS=' ') ou bien tu remplaces lespace par un \n puis tu ouput la ligne dans un fichier. Et apres tu grep chaque ligne du fichier temporaire


Merci pour ton aide;

je ne sais pas ce que tu entends par IFS.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Iroh
Membre Relatif
Messages: 374
Enregistré le: 14 Oct 2008, 20:24

par Iroh » 10 Nov 2013, 17:53

Salut*,

sinon sans modifier IFS en utilisant read:
Code: Tout sélectionner
while read line; do
    tradword=""
    for word in $line; do
        tradword="$tradword $(grep -i $word f2.txt | cut -d' '  -f2)"
    done
    echo $tradword
done < f1.txt

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 11 Nov 2013, 16:52

Bonjour; j'ai utilisé la même syntaxe que toi; mis à part au niveau de la ligne echo; où j'ai concaténé dans un fichier f3.
L’exécution est bonne. En revanche je ne comprends pas la totalité du code.

Je ne sais pas ce que fais l'option -i du grep; je l'ai mentionné dans mon cours mais je n'ai pas sa description; et lorsque je fais un man du grep je n'ai pas trouvé l'option -i; il y a seulement -I mais je suppose que ce n'est pas la même.

Merci à vous.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Iroh
Membre Relatif
Messages: 374
Enregistré le: 14 Oct 2008, 20:24

par Iroh » 11 Nov 2013, 18:25

Code: Tout sélectionner
grep [OPTIONS] PATTERN [FILE...]
       -i, --ignore-case
              Ignore  case  distinctions  in  both  the  PATTERN and the input
              files.  (-i is specified by POSIX.)


C'est pour ne pas tenir des des minuscules/majuscules.

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 08:03

par ampholyte » 12 Nov 2013, 09:56

Bonjour,

Lorsque tu ne connais pas ce que fait une commande ou un argument d'une commande, le premier reflexe est de faire un
Code: Tout sélectionner
man ma_commande
.

Tu auras ainsi une description complète de ce que tu cherches.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 12 Nov 2013, 13:23

ampholyte a écrit:Bonjour,

Lorsque tu ne connais pas ce que fait une commande ou un argument d'une commande, le premier reflexe est de faire un
Code: Tout sélectionner
man ma_commande
.

Tu auras ainsi une description complète de ce que tu cherches.


Oui je sais c'est ce que j'ai fait sur mon grep; mais je n'ai pas trouvé l'option en question soit car elle n'y était pas ou alors je ne l'ai tout simplement pas vu dans la liste d'option.

Merci pour votre aide :lol3:
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 13 Déc 2013, 11:59

Salutation; je ne comprends pas la commande suivante pourriez vous me l'expliquer ?

Code: Tout sélectionner
echo "$2+- ‘basename $fich‘"


basename va nous donner le nom du fichier sans son extension si je ne me trompe pas.

$2 n'a aucune valeur courante dans le script; il n'a pas été affecté donc par défaut je pense qu'il vaut la chaine vide.

Ce qui voudrait dire que la commande écrite : espace +- nom_fcihier ????


Je vous passe le code complet mais c'est la seule commande que je ne comprends pas.


Code: Tout sélectionner
#! /bin/sh
#******************#
# Mauvaise syntaxe #
#******************#
if [ $# -eq 0 -o $# -gt 2 ]

then
echo "Usage : $0 nom_répertoire" >&2
exit 1
fi
#**************************************************#
# Au premier appel, affichage du nom du répertoire #
#**************************************************#
if [ $# -eq 1 ]
then
if [ ! -d "$1" -o ! -r "$1" -o ! -x "$1" ]
then
echo "Le repertoire $1 n’existe pas ou est protege !" >&2
exit 2
fi
echo $1
fi
#************************************************************#
# Calcul prealable du nombre de repertoires du repertoire $1 #
#************************************************************#
nbrep=0
for fich in "$1"/*
do
if [ -d "$fich" ]
then
nbrep=‘expr $nbrep + 1‘
fi
done
#**********************************************#
# Pour chaque repertoire de $1, appel recursif #
#**********************************************#
for fich in "$1"/*
do
if [ -d "$fich" ]
then
#***********************#
# Affichage d’une ligne #
#***********************#
echo "$2+- ‘basename $fich‘"
#*************************************************#
# Si le repertoire est accessible en modes r et x #
#*************************************************#
if [ -r "$fich" -a -x "$fich" ]
then
#**************************************#
# Si on affiche le dernier d’une série #
#*********************
then
#************************************************#
# Appel recursif, avec un espace à la place du | #
#************************************************#
"$0" "$fich" "$2
"
#*******#
# Sinon #
#*******#
else
#******************************************#
# Appel recursif, avec un | supplementaire #
#******************************************#
"$0" "$fich" "$2| "
fi
fi
nbrep=‘expr $nbrep - 1‘
fi
done
exit 0
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Déc 2013, 13:56

Autre petite question; y a t'il une syntaxe pour vérifier q'un paramètre d'un script est une archive d'une part ? au format tar d'autre part ? comme on ferait un [-d fichier] pour vérifier si fichier est un répertoire.


Par ailleurs; comment devrait on s'y prendre pour transformer une ligne en colonne et vice versa ? J'ai déjà essayé d'inclure \n sur un affichage du type echo en récupérant la sortie d'un ls par exemple mais ça ne marche pas.

Si je fais un echo `ls rep` j'aurais la liste des dossier et fichier d'un rep sur une ligne à priori; mais afin de pouvoir mieux travailler sur la liste j'aimerais pouvoir faire en sorte d'avoir un mot par ligne; autrement je suis obligé de faire le travail mot par mot avec un fichier temporaire; pas forcement gênant, mais plus coûteux en rapidité je pense.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Déc 2013, 14:10

Ce qui voudrait dire que la commande écrite : espace +- nom_fcihier ????

tu peux tester.

y a t'il une syntaxe pour vérifier q'un paramètre d'un script est une archive d'une part

non.

comme on ferait un [-d fichier] pour vérifier si fichier est un répertoire.

shell ne propos pas à ma connaissance de paramètre comme -d où -f pour reconnaitre une archive. En revanche, tu peux faire un
Code: Tout sélectionner
[ "application/x-gzpdf" == "$(mimetype -b fichier)" ]

où tu la listes la liste des archives que tu veux supporter

Si je fais un echo `ls rep` j'aurais la liste des dossier et fichier d'un rep sur une ligne à priori; mais afin de pouvoir mieux travailler sur la liste j'aimerais pouvoir faire en sorte d'avoir un mot par ligne;

ls -c1 pour lister sur une seule colonne. idem un mot par ligne.
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Déc 2013, 14:52

ls -c1 pour lister sur une seule colonne. idem un mot par ligne.


Je connaissais pas cette option merci.

où tu la listes la liste des archives que tu veux supporter


J'avoue ne pas avoir compris cette ligne de code; si je voulais l'adapter pour une archive tar il me faudrait écrire quoi ?

A défaut de pouvoir tester s'il s'agit d'une archive, on peut peut être tester si c'est un répertoire ou un fichier. Si ce n'est ni l'un ni l'autre ça enlève déjà quelques possibilités. A moins qu'une archive soit considéré comme un répertoire ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Déc 2013, 15:04

J'avoue ne pas avoir compris cette ligne de code; si je voulais l'adapter pour une archive tar il me faudrait écrire quoi ?

ben tu regardes ca donne quoi mimetype -b tonarchive, tu récupères le mimetype et tu adaptes...
il faut [CENTER]TESTER[/CENTER]

A moins qu'une archive soit considéré comme un répertoire ?

testes!!!!
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Déc 2013, 16:59

Une archive n'est pas considéré comme un répertoire mais j'ai pu me débrouiller autrement.

En revanche, je bloque sur une de mes boucles

Je voudrais faire un truc

Pour k allant de 3 à $#
et là je fais un test entre une variable et le paramètre positionnel $k


Code: Tout sélectionner
for k in 3-$#
      do
         if [ -d $k -o ! -r $k ]
         then
            echo "Usage: $k n'est pas un fichier accessible";
            exit 3;


Mais ça ne marche pas car par exemple lorsque je fais un appel $k va prendre la valeur 3-3 au lieu de la liste des cas qui du coup ferait référence au paramètres du script. Je pensais qu'il s'agissait de la bonne syntaxe pour faire une liste de cas successif mais à priori je me trompais.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Déc 2013, 17:06

pourquoi pas
Code: Tout sélectionner
k=3
while [ $k -le $# ];do
  k=$(($k+1))
done
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Déc 2013, 17:28

fatal_error a écrit:pourquoi pas
Code: Tout sélectionner
k=3
while [ $k -le $# ];do
  k=$(($k+1))
done


Certes ça marche; mais j'aurais quand même voulu savoir comment j'aurais pu faire une liste avec le for ;)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Déc 2013, 17:56

pour shell
Code: Tout sélectionner
for i in $(seq 3 $#);do
  echo $i
done


pour bash ici

tu avais cherché sur le net?
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Déc 2013, 18:11

fatal_error a écrit:pour shell
Code: Tout sélectionner
for i in $(seq 3 $#);do
  echo $i
done


pour bash ici

tu avais cherché sur le net?


oui mais peut être pas au bon endroit..la plupart des exemples montrent une liste de cas totalement énuméré...



Par contre j'ai un autre petit soucis qui me casse la tête x) :mur:

Disons que le paramètre $2 vaut toto

a=2;

Si je veux afficher la valeur toto à partir de a.

J'ai testé plusieurs idées aucune ne marche

$$a va agir en prenant d'abord en compte $$ donc ça merde.
\$$a va retourner $2 mais ne vas pas donner sa valeur.
le backquote ne marche pas non plus sachant que je n'ai pas de commande.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Déc 2013, 18:21

ce mécanisme s'appèle eval, je te laisse approfondir sur le net.
Code: Tout sélectionner
echo ${2}
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Déc 2013, 18:48

fatal_error a écrit:ce mécanisme s'appèle eval, je te laisse approfondir sur le net.
Code: Tout sélectionner
echo ${2}



Bizarrement chez moi ça plante (peut être en partie parce que je veux utiliser eval dans une comparaison mais je ne crois pas quand même).


J’appelle mon script de cette façon


script.sh [-p] archive.tar fichier.txt [...]

Je traite pour le moment le cas avec l'option

Et si il y a un ou des fichiers passé en paramètre présent dans l'archive je dois afficher le chemin de ces fichiers.


Je vais sauter les test du nombre de paramètres ainsi que celui qui détectait sur l'option est présente ou pas; ils sont fonctionnels.
Code: Tout sélectionner
val=0;
if [ $1 = -p ]
then
   
   for i in `tar -tf $2`
   do
      for k in $(seq 3 $#)
      do
         if [ -d `eval echo \$$k` -o ! -r `eval echo \$$k` ]
         then
            echo "Usage: `eval echo \$$k` n'est pas un fichier accessible";
            exit 3;
         fi
         if [ -f $k ]
         then
            if [ `basename $i` = $k ]
            then
               pwd;
               val=`expr $val + 1`;
            fi
         fi
         k=`expr $k +1`;
      done
   done
if [ $val -eq 0 ]
then
   exit 4;
fi
exit 0;


Lorsque je lance donc avec 3 paramètres c’est à dire

script.sh -p archive.tar fichier.txt

J'obtiens l'erreur me disant que: 18778k n'est pas un fichier accessible

Cela veut donc dire que le eval n'évalue pas correctement car normalement je devrais avoir fichier.txt comme valeur de $3 dans cet exemple; en réalité je ne devrais même pas entrer dans l'erreur d'usage sachant que le fichier est bien accessible.

Une idée ?

EDIT; j'ai pas encore modifié les valeurs pour k après le test défaillant; la problème se situe avant de toute façon.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite