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 :

Script Bash pour changer fichier par itération


Sujet :

Shell et commandes GNU

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Par défaut Script Bash pour changer fichier par itération
    Bonjour,

    J'aimerais faire un script bash qui, en itérant :

    - ouvre un fichier en csh
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/bin/csh 
    #output file
    set ps=energy.ps
    #time step to plot
    set ts=230
    [...]
    - change la valeur de ts de +10 (par exemple)

    - lance le csh

    - enregistre le plot qui en résulte (donc changer de nom de la figure avec l'incrément)

    - et recommence autant de fois désiré.

    Une idée pour me lancer?

    Merci d'avance

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Par défaut
    j'ai déjà commencé avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
    for ((i = 000; i <= 700; i += 50))
    do
    echo $i
     
     
    sed -i 's/^set ts=.*/set ts=666/' filename
    grep '^set ts=' filename || { echo; echo 'set ts=666'; } >>filename
     
    done
    mais je pense que je vais avoir du mal pour l'itération et l'enregistrement de la figure.

  3. #3
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 411
    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 411
    Par défaut
    Bonjour,

    Un peu barbare, la méthode ici, je te suggère de modifier ton script csh pour qu'il puisse prendre des paramètres au lieu de le modifier avant exécution.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Par défaut
    Merci pour ta réponse mais je trouve encore moins d'aide en csh qu'en bash.

    Rien que pour faire les entrées et la boucle j'ai du mal,

    par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/csh 
    echo "entree temps max en sec (<1000)"
    set max_iter = $<
    echo "entree le pas de temps en sec"
    set pas_iter = $<
    set iter=0
     
     
    while ($iter<$max_iter)
    echo $iter
    set iter=`exp $iter + 1`
    end
    il me ressort "0 illegal variable name.."

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Attention: les nombres commençant par le chiffre '0' sont considérés comme étant écrits en octal, ce qui peut changer leur valeur (sauf pour le nombre '0'). Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ for ((i = 000; i <= 0700; i += 050)); do echo $i; done
    0
    40
    80
    120
    160
    200
    240
    280
    320
    360
    400
    440
    Il faut utiliser les guillemets (double quotes) pour pouvoir utiliser la valeur d'une variable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/bash
    filename="./filename"
    for ((i = 0; i <= 700; i += 50))
    do
      echo $i
      sed -i "s/^set ps=.*/set ps=energy-$i.ps/; s/^set ts=.*/set ts=$i/" ${filename}
      # lancement de la commande?
      ${filename}
    done
    Mais je plussoie la remarque de disedorgue: il vaudrait mieux passer $i en argument au script:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/bash
    filename="./filename"
    for ((i = 0; i <= 700; i += 50))
    do
      echo $i
      # lancement de la commande?
      ${filename} $i
    done
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #!/bin/csh
    set i=$1
    #output file
    set ps=energy-$i.ps
    #time step to plot
    set ts=$i
    [...]

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par Newenda Voir le message
    Merci pour ta réponse mais je trouve encore moins d'aide en csh qu'en bash.
    Ça ne m'étonne pas!

    Es-tu certain de vouloir absolument le faire en csh?

    Rien que pour faire les entrées et la boucle j'ai du mal,

    par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/csh 
    echo "entree temps max en sec (<1000)"
    set max_iter = $<
    echo "entree le pas de temps en sec"
    set pas_iter = $<
    set iter=0
     
     
    while ($iter<$max_iter)
    echo $iter
    set iter=`exp $iter + 1`
    end
    il me ressort "0 illegal variable name.."
    Bizarre...

    Chez moi, les entrées et la boucle fonctionnent bien (après avoir changé "exp" en "expr" et "+ 1" en "+ $pas_iter")

  7. #7
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 411
    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 411
    Par défaut
    C'est peut-être aussi l'occasion de changer le csh en un shell plus dans l'air du temps...

    Que fait au juste ce script csh ?
    Est-il si lourd à transformer en un shell de style sh, ksh, ou bash ?

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Par défaut
    Merci pour vos réponses,

    Citation Envoyé par jack-ft Voir le message

    Chez moi, les entrées et la boucle fonctionnent bien (après avoir changé "exp" en "expr" et "+ 1" en "+ $pas_iter")
    Effectivement ça marche, le message d'erreur ne m'a pas aidé

    J'aimerais bien l'écrire en bash mais j'y connais pas grand chose comme vous avez pu le constater.

    Le script va lire une série de fichier fieldt* et utiliser GMT pour faire une figure de propagation ondulatoire. Voici pour l'instant la version modifiée (modif pour la boucle en gras) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #!/bin/csh
    
    echo "entree temps max en sec (<1000)"
    set max_iter = $<
    echo "entree le pas de temps en sec"
    set pas_iter = $<
    set iter=0
    
    while ($iter<$max_iter)
    echo $iter
    
    #output file
    set ps=energy.ps
    #time step to plot
    set ts=iter
    #set energy amplitude:
    set maxamp=5e-31
    #image size (in cm)
    set xsize=25
    set ysize=5
    #domain bounday (km)
    set xmin=0
    set xmax=100
    set ymin=0
    set ymax=20
    #do you need to plot the mesh (0) or not (1)
    set addmesh=0
    #---------------------------------------------
    gmtset PAPER_MEDIA = A4
    set j="-JX${xsize}c/${ysize}c"
    set R="-R${xmin}/${xmax}/${ymin}/${ymax}"
    set list=`\ls fieldt000.*`
    set info=`echo 0.0 0.1 0.1 1.`
    set list=`\ls fieldt*.*"$ts"`
    if (-e tmp.tmp) \rm tmp.tmp
    foreach f($list)
    awk '{print $1/1000.,$2/1000,$3/'$maxamp'}' $f>> tmp.tmp
    end
    surface tmp.tmp  -Gtmp.grd -I0.1/0.1 -T0.6  $R
    gmtset D_FORMAT = "%.3g"
    makecpt -Chot  -Z -I  -T$info[1]/$info[2]/$info[3] > cptf
    set tt=`awk '{if (NR==4) printf("t=%3.1fs\n",$1*10*'$ts')}' input.spec `
    gmtset LABEL_FONT_SIZE = 14p
    gmtset ANOT_FONT_SIZE = 12p
    grdimage tmp.grd -BEWSa10:"$tt"::,"km":/10:,"km":  $j -Y5c -X4c  $R -Ccptf -K > $ps
    if ( $addmesh == 0 ) then
       awk '{if (NF==2) {print $1/1000,$2/1000}else{print $0}}' mesh.gnu > toto.gnu
       psxy  -W0.1p/155/155/155  $R $j  -m toto.gnu  -O -K >> $ps
    endif
    set fs=`awk '{if (NR==17) print $1}' input.spec`
    awk '{if (NR>2) {print ($1+250)/1000,($2+250)/1000,10,0,0,2,NR-2}}' $fs > toto.gnu
    pstext $R $j -G255/0/0   -O -K  toto.gnu >> $ps
    awk '{if (NR>2) {print $1/1000,$2/1000}}' $fs > toto.gnu
    psxy  $R $j   -Sd0.2  toto.gnu   -O -K >> $ps
    awk '{if (NR==10) print $1/1000,$2/1000}' input.spec > toto.gnu
    psxy  $R $j   -Sa0.3  toto.gnu   -O  >> $ps
    gv $ps
    
    set iter=`expr $iter + $pas_iter`
    end
    mais me sors toujours la même figure avec ce message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    0
    ls: No match.
    surface: cannot open input data file tmp.tmp

    voyez vous l'erreur ou bien est ce facile de mettre en bash?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 718
    Par défaut
    Bonjour,

    facile de mettre en bash?
    oui.
    il y a beaucoup d'assignations de variables, quelques tests, et des commandes externes qui ne devraient pas changer d'un shell à l'autre.

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Bonjour,

    oui.
    il y a beaucoup d'assignations de variables, quelques tests, et des commandes externes qui ne devraient pas changer d'un shell à l'autre.
    Merci mais j'ai l'impression d'y être presque et que la transformation en bash serait inutile surtout qu'à la base c'est pas mon code du tout.

    J'ai rééditer mon code de mon dernier message, voyez vous l'erreur?

    Merci d'avance

  11. #11
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par Newenda Voir le message
    mais me sort toujours la même figure avec ce message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    0
    ls: No match.
    surface: cannot open input data file tmp.tmp

    voyez vous l'erreur ou bien est ce facile de mettre en bash?
    Hmmm...

    Je plussoie la conversion en bash: tu auras BEAUCOUP plus d'aide qu'en csh!

    Je t'invite à commencer la conversion en bash et, en cas de problème, tu postes tes difficultés ici et tu auras plein d'aide sur ce forum!

    Sinon, le message ls: No match indique que "ls" n'a pas trouvé de fichiers correspondant au pattern fourni.

    Ce message provient d'un appel à "ls" (t'as de la chance que N_BaH ne l'ait pas vu...) donc de la ligne 32 ou 34.

    Pour en avoir le coeur net, il suffit de faire un "echo" pour voir à quel moment se produit l'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    set list=`\ls fieldt000.*`
    echo "Ici, list contient '$list'"
    set info=`echo 0.0 0.1 0.1 1.`
    set list=`\ls fieldt*.*"$ts"`
    echo "et maintenant, list contient '$list'"
    D'ailleurs, à quoi sert la première affectation de "list", puisqu'elle est écrasée juste après???

    De toute manière, il est préférable de supprimer l'appel à "ls" (ça va apaiser N_BaH) et modifier le "foreach":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach f(fieldt*.*$ts)
    Ensuite, il est probable que "$list" ne contienne rien, ce qui expliquerait le message suivant surface: cannot open input data file tmp.tmp, car la boucle "foreach" serait alors exécutée 0 fois et n'alimenterait pas le fichier "tmp.tmp".

    En fait, je viens de trouver une autre erreur qui explique probablement une partie des problèmes...

    À la ligne 15, manifestement il manque des sous... Il faut ajouter un "$" devant "iter", de manière à ce que "ts" contienne une "bonne" valeur!

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Par défaut
    Citation Envoyé par jack-ft Voir le message

    En fait, je viens de trouver une autre erreur qui explique probablement une partie des problèmes...

    À la ligne 15, manifestement il manque des sous... Il faut ajouter un "$" devant "iter", de manière à ce que "ts" contienne une "bonne" valeur!
    Merci, le problème était là..

    J'aurais une dernière question: le nom de sortie est energy.ps

    J'aimerais donner un nom différent pour chaque itération tel que "enerrgy$iter.ps" mais je ne vois pas comment définir un nouveau nom mélangeant les caractères et le variable $iter.

    Merci d'avance.

  13. #13
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par Newenda Voir le message
    J'aurais une dernière question: le nom de sortie est energy.ps

    J'aimerais donner un nom différent pour chaque itération tel que "enerrgy$iter.ps" mais je ne vois pas comment définir un nouveau nom mélangeant les caractères et le variable $iter.


    J'ai déjà donné la réponse dans une réponse précédente (4ème code, ligne 4)

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Par défaut
    Citation Envoyé par jack-ft Voir le message


    J'ai déjà donné la réponse dans une réponse précédente (4ème code, ligne 4)
    oups pardon effectivement. c'est ce que j'écrivais d'ailleurs, j'avais tout de même du l'avoir en tête.

    Merci !

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

Discussions similaires

  1. Script bash pour correspondance entre fichiers .DOT (GraphViz)
    Par Miel56 dans le forum Administration système
    Réponses: 1
    Dernier message: 17/02/2015, 17h01
  2. Script bash pour parcourir la variable Path
    Par harris_macken dans le forum Shell et commandes GNU
    Réponses: 16
    Dernier message: 13/02/2008, 23h15
  3. Script bash pour grub
    Par mplcd dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 04/12/2007, 13h44
  4. Réponses: 1
    Dernier message: 09/02/2007, 23h51
  5. script windows pour copier fichier
    Par sacan dans le forum Windows
    Réponses: 3
    Dernier message: 09/06/2006, 13h24

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