IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Problème de calcul dans sed


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 14
    Par défaut Problème de calcul dans sed
    Bonjour.

    Pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo 300 euros | sed "s/[0-9]*/$(( & - 2 ))/g"
    renvoit-il
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bash: & - 2  : erreur de syntaxe : opérande attendue (le symbole erroné est "& - 2 ")
    au lieu de sortir "298 euros" ?

    Merci d'avance.

  2. #2
    Membre éprouvé Avatar de RaphaelG
    Homme Profil pro
    Amateur
    Inscrit en
    Juin 2016
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Amateur

    Informations forums :
    Inscription : Juin 2016
    Messages : 94
    Par défaut
    Je ne suis pas le guru de sed et je comprends rien à ta commande.
    Mais c'est la première fois que je vois quelqu'un essayer de faire des calculs avec sed.
    D'habitude en shell, on utilise la built in command expr ou bc.

    Exemple avec bc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    brouillons$ echo "300 - 2" | bc
    298
    brouillons$
    Exemple avec expr:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    brouillons$ echo 300 euros | expr $(awk '{print $1}') - 2
    298
    brouillons$
    Pour reproduire exactement l'affichage que tu recherches :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    brouillons$ echo 300 euros | awk '{print ($1 - 2) " " $2}'
    298 euros
    brouillons$
    En espérant t'avoir aidé.

  3. #3
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    Citation Envoyé par RaphaelIG
    on utilise la built in command exp
    wrong ! exprest une commande externe.
    expr n'a déjà pas de sens dans un shell un peu moderne, mais expr| awk, c'est vraiment très moyen
    ta dernière proposition est bien meilleure.

    et, non, sed ne sait pas compter.

    Edit : ah ! j'ai retrouvé : sed ne sait pas compter, mais
    il peut exécuter des commandes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    echo 300 euros | sed 's/[0-9]*/echo $(( & - 2 ))/e'
    298 euros
    en général, dans des cas comme celui-là, je passe à awk, qui possède des capacités de calcul très importantes.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 358
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 358
    Par défaut
    Bonjour,

    Pour moi, l'execute du sed est buggé (voir le deuxième cas) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ echo 300 euros | sed 's/[0-9]*/echo $(( & - 2 ))/e'
    298 euros
    $ echo il y a 300 euros | sed 's/[0-9]*/echo $(( & - 2 ))/e'
    -2il y a 300 euros
    Dans le cas donné, cela fonctionne, et donc si c'est un cas comme ça, on peut le faire en builtin:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ XX="300 euros"
    $ echo $((${XX//[^0-9]/}-2))${XX//[0-9]}
    298 euros

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    Bonjour,

    Citation Envoyé par disedorgue Voir le message
    Bonjour,

    Pour moi, l'execute du sed est buggé (voir le deuxième cas) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $ echo il y a 300 euros | sed 's/[0-9]*/echo $(( & - 2 ))/e'
    -2il y a 300 euros
    Je ne dirais pas que c'est buggé car
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    echo il y a 300 euros | sed 's/[0-9]*/&/'
    il y a 300 euros
    renvoie la phrase complète et pas uniquement les chiffres.
    Comme ça, on obtient le résultat attendu.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    echo il y a 300 euros | sed 's/\(.* \)\([0-9]*\)\( .*\)/echo \1 $(( \2 - 2 )) \3/e'
    il y a 298 euros
    Ici , on construit la commande dans le patern space.
    Je n'arrive pas a trouver la syntaxe pour utilser cat fichier par exemple pour insérer fichier avant le patern space et remplacer la commande r qui va insérer fichier après le patern space

    Si quelqu'un a une idée ?

    Cordialement.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    Citation Envoyé par ctac_ Voir le message
    Je n'arrive pas a trouver la syntaxe pour utilser cat fichier par exemple pour insérer fichier avant le patern space et remplacer la commande r qui va insérer fichier après le patern space
    En fait c'est tout simple ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed '/Texte_Cherché/e cat fichier' fichier_de_travail
    Cordialement.

  7. #7
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Pour moi, l'execute du sed est buggé (voir le deuxième cas) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ echo 300 euros | sed 's/[0-9]*/echo $(( & - 2 ))/e'
    298 euros
    $ echo il y a 300 euros | sed 's/[0-9]*/echo $(( & - 2 ))/e'
    -2il y a 300 euros
    En fait, il n'est pas buggé et fait exactement ce qu'on lui demande. Seulement dans le deuxième cas la première position de la chaîne comptant entre zéro ou plusieurs chiffres est la chaîne vide au début de la chaîne. Pour éviter ça, il faudrait imposer au moins un chiffre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    echo il y a 300 euros | sed 's/[0-9][0-9]*/echo $(( & - 2 ))/e'
    il y a 298 euros

  8. #8
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 358
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 358
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    En fait, il n'est pas buggé et fait exactement ce qu'on lui demande. Seulement dans le deuxième cas la première position de la chaîne comptant entre zéro ou plusieurs chiffres est la chaîne vide au début de la chaîne. Pour éviter ça, il faudrait imposer au moins un chiffre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    echo il y a 300 euros | sed 's/[0-9][0-9]*/echo $(( & - 2 ))/e'
    il y a 298 euros
    Etrange, chez moi, ça ne fonctionne pas (et pourtant, ce que tu dis me semble tout à fait logique) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo 'il y a 300 euros' | sed 's/[0-9][0-9]*/echo $(( & - 2 ))/e'
    sh: 1: il: not found
    Mais pour le coup, c'est ctac_ qui à raison

  9. #9
    Membre éprouvé Avatar de RaphaelG
    Homme Profil pro
    Amateur
    Inscrit en
    Juin 2016
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Amateur

    Informations forums :
    Inscription : Juin 2016
    Messages : 94
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    wrong ! exprest une commande externe. ...
    Oui, au temps pour moi, expr est bien une commande externe.

    expr n'a déjà pas de sens dans un shell un peu moderne, mais expr| awk, c'est vraiment très moyen
    L'OP n'a pas précisé avec quel shell il travaille. Si il utilise du pur bourne shell (si si, ça existe encore sous Solaris par exemple) ou si il utilise le dash de Debian, les "$((compteur+1))" et "let compteur=compteur+1" ne fonctionnent pas.
    J'ai utilisé un awk, pour récupérer le 1er champ de sa commande echo. C'était juste pour illustrer l'usage d'expr qui a l'avantage de marcher partout (dash, bash, ... mais c'est normal, c'est une commande externe ) au risque de paraître un peu old school.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo 300 euros | sed 's/[0-9]*/echo $(( & - 2 ))/e'
    Pourrais tu nous en dire plus ?
    Comment sed sait que "echo $(( & - 2 ))" est une commande à exécuter plutôt qu'une expression rationnelle devant se substituer à "[0-9]*" ?
    Que veut dire le "/e" à la fin ?

  10. #10
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    Citation Envoyé par RaphaelG
    [...]si il utilise le dash de Debian, les "$((compteur+1))" et "let compteur=compteur+1" ne fonctionnent pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ dash
    $ echo $(( 2 + 2 ))
    4
    ah, bon.
    Citation Envoyé par RaphaelG
    Pourrais tu nous en dire plus ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    info sed 'Extended Commands'
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 14
    Par défaut
    En effet @disedorgue, la formule du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo il y a 300 euros | sed 's/[0-9]*/echo $(( & - 2 ))/e'
    ne fonctionne pas dans mon cas de figure (plus compiqué que ma simple demande avec 300 euros...
    Mais j'ai trouvé une solution grâce à @ctac_ et sa proposition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo il y a 300 euros | sed 's/\(.* \)\([0-9]*\)\( .*\)/echo \1 $(( \2 - 2 )) \3/e'
    J'arrivais à obtenir ce que je voulais avec des variable, mais voulais réussir à le faire en une seule ligne, c'est chose faite. J'ai pu comparer les deux scripts (avec variables ou "en une ligne"), il mettent (sensiblement) le même temps à s’exécuter. Le but était de récupérer un chat Twitch et le convertir au format fichier ".srt" pour le joindre à la vidéo, ce qui prend, dans les deux cas, plus ou moins 2min30 pour une heure de vidéo (config pas très puissante).

    Je mets mes deux scripts dans les deux prochains posts (je ne mets pas de sortie vers un fichier dans ces exemples). J'ai mis le calcul du temps écoulé au sein du script, bien qu'on peut tout aussi bien l'obtenir avec

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de calcul dans un IF
    Par CélineM dans le forum SAS Base
    Réponses: 2
    Dernier message: 06/05/2008, 15h20
  2. Réponses: 17
    Dernier message: 02/04/2007, 17h39
  3. Problèmes de calcul dans une requete imbriquée
    Par LeNovice dans le forum Langage SQL
    Réponses: 6
    Dernier message: 21/03/2007, 16h56
  4. Problème graphique & calcul dans champ
    Par jacquesprogram dans le forum Access
    Réponses: 1
    Dernier message: 08/09/2006, 15h09
  5. problème de calcul dans un formulaire
    Par Bray02 dans le forum IHM
    Réponses: 1
    Dernier message: 07/12/2005, 11h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo