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 :

Méthode pour substituer


Sujet :

Shell et commandes GNU

  1. #1
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut Méthode pour substituer
    Bonsoir,
    J'ai un fichier dans lequel j'ai déjà filtré les enregistrements que je souhaitais via un sed -n.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat $fic | sed -n '/30076/p' |  sed -n '/2019/p'  > $fictmp
    Maintenant dans ce fichier $fictmp j'ai une date sur toutes les lignes de la forme YYYYMM.
    Soit je récupère ma valeur qui se trouve toujours en position 5 sur 6 caractères et je substitue celle-ci par ma varibale que j'ai passé en paramètre (mais cela est très lourd vu le nombre de lignes de mes fichiers en entrée, et en plus cela ne fonctionne pas parfaitement), soit je ne travaille plus ligne par ligne, mais sur tout le fichier $fictmp et je lui demande de modifier les valeurs de la position 5 à 10 par celle du paramètre.

    Savez vous comment faire cela ?
    Merci

  2. #2
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat $fic | sed -n '/30076/p' |  sed -n '/2019/p'  > $fictmp
    est facilement obtimisable par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n '/30076|2019/p' $fic > $fictemp
    pour éviter les 3 pipes .... gagner donc beaucoup de temps.

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Citation Envoyé par frp31 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n '/30076|2019/p' $fic > $fictemp
    Il faut protéger le "pipe" avec sed à l'instar de "grep" ou utiliser l'option "-r" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sed -n '/30076\|2019/p' $fic
    ou
    sed -nr '/30076|2019/p' $fic
    De plus le pipe est ici synonyme de OU l'un OU l'autre alors que je pense que la finalité (mais je peux me tromper) est ET l'un ET l'autre, qui se traduirait par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n '/30076/p' $fic | sed -n '/2019/p'
    ou avec grep
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep '30076'  $fic | grep '2019'
    et qu'on pourrait réduire à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n '/30076.*2019\|2019.*30076/p' $fic
    ou avec grep :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep -E '30076.*2019|2019.*30076'
    Si toutefois on recherche à la fois une ligne contenant "30076" ET "2019" dans n'importe quel ordre...

    Mais je le répète, j'ai peut être mal interprété la demande et dans ce cas là j'ai tout faux (ou presque, la protection du pipe étant exacte), et je m'en excuse par avance

  4. #4
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    Merci bien.
    Ca va me permettre d'optimiser.
    Mais si j'ai d'autres "couples" de valeurs à chercher dans mes enregistrements, est-il préférable de rajouter des lignes tel que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    sed -n '/30076|2020/p' $fic >> $fictemp
    sed -n '/30080|2022/p' $fic >> $fictemp
    ou dois-je faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n '/30076|30080|2020|2022/p' $fic >> $fictemp
    Mais pour revenir à ma question de susbtitution que me conseillez-vous ?
    Car maintenant je suis sur la ligne et non sur la totalité du fichier.
    Je veux remplacer la valeur existante de la position 5 à 10 incluse par celle amenée en paramètre yyyymm.

    Si j'ai la valeur 201012 (dans mon fichier pos 5 à 10) et qu'en paramètre j'ai mis 201105, il me faut dans tout le fichier mettre 201105.

    Merci bien.

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Attention de bien relire les explications au-dessus concernant la protection du "pipe" avec "sed".

    Pour les couples il faut utiliser la syntaxe (utilisation de l'option "-r", puis des parenthèses et des pipes) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -nr '/(30076.*30080|30080.*30076)|(2020.*2022|2022.*2020)/p' $fic
    Par contre tu n'as toujours pas dit si l'ordre de recherche était un critère, par exemple est-ce qu'il faut rechercher une ligne contenant le couple "30076 et 30080" dans cet ordre ou aussi comme "30080 et 30076" ?

    Pour le reste de ta demande un exemple concret serait le bienvenu merci.

  6. #6
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    je viens de tester cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    123 sed -n '/30076\|2019/p' $fic
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -nr '/30076|2019/p' $fic
    Mais cela ne fonctionne pas.
    1er cas : résultat NULL
    2ème cas : message d'erreur

  7. #7
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Pour le reste de ta demande un exemple concret serait le bienvenu merci.
    +1 on ne comprend plus rien là donne un exemple concret !

    edit: et pense à donner le message d'erreur aussi tant qu'on y est

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Quel système ?
    Quelle distrib ?
    Quelle version de "sed" ?

    On peut avoir un bout de ton fichier histoire qu'on teste de notre côté...

    Un exemple où on cherche "toto suivi de tata ou tata suivi de toto" ou "tutu suivi de tyty ou tyty suivi de tutu" :

    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
    $ cat plop
    toto et tata
    tata et toto
    toto et titi
    titi et tata
    tutu et tyty
    tyty et tutu
    tutu et titi
    titi et tyty
    
    $ sed -nr '/(to.*ta|ta.*to)|(tu.*ty|ty.*tu)/p' plop
    toto et tata
    tata et toto
    tutu et tyty
    tyty et tutu

  9. #9
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Attention de bien relire les explications au-dessus concernant la protection du "pipe" avec "sed".

    Pour les couples il faut utiliser la syntaxe (utilisation de l'option "-r", puis des parenthèses et des pipes) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -nr '/(30076.*30080|30080.*30076)|(2020.*2022|2022.*2020)/p' $fic
    Par contre tu n'as toujours pas dit si l'ordre de recherche était un critère, par exemple est-ce qu'il faut rechercher une ligne contenant le couple "30076 et 30080" dans cet ordre ou aussi comme "30080 et 30076" ?

    Pour le reste de ta demande un exemple concret serait le bienvenu merci.
    bien vu

  10. #10
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    La version du système :
    SunOS devece 5.10 Generic_142900-03 sun4u sparc SUNW,Sun-Fire-15000

    Je suis en ksh.
    Pour la version de sed, je ne sais pas où trouver cela.

    Un bout du fichier :
    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
    1LCEPTFDAI20110401
    5DAI2011031010228096280229814527800200000000010310.11+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011030210228096280229814859500200000000007599.73+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011030810228096280264510010200200000000001282.85+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011031010228096280264510010200200000000001861.76+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011030810228096280264510022600200000000005287.81+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011030910228096280264510022600200000000026842.73+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011030410228096280264510032300200000000003038.07+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011030810228096280264510085400200000000098065.06+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011033008020226280264510091900200000000001480.66+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011031010228096280264510091900200000000011098.14+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    5DAI2011030310228096280264510098600200000000005447.84+850CREDIT DES REMISES A L'ENTREE                     072ESCOMPTE EFFETS COMMERCE
      00030CR61
    Est-ce que cela vous va ces 12 lignes ?
    Seule la ligne avec les valeurs en gras sera sélectionnée dans cet exemple.

  11. #11
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    Ca nous va parfaitement, maintenant, que cherches-tu à faire exactement ?

    Si j'ai bien compris ton premier post, tu veux trouver les lignes qui contiennent 30076 et 2019.

    Et ensuite, tu veux remplacer les 6 caractères en position 5 (qui correspondent à une date au format YYYYMM) par d'autres caractères ?

    En perl, ça donnerait ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -ple 'substr($_,4,6)="201104" if (/64510/ && /2002/);' test > test2
    L'option -p indique qu'on va lire chaque ligne du fichier, stocker la ligne lue dans une variable nommée $_ et à la fin des éventuels traitements, on affiche cette variable $_.
    L'option -l indique que pour traiter chaque ligne, on retire déjà le symbole fin de ligne s'il est présent à la fin de la ligne, et qu'après avoir affiché la ligne, on ajoute à nouveau le symbole de fin de ligne (très utile pour contourner les problèmes de fin de ligne entre les OS et pour éviter d'être ennuyé par les sauts de lignes).
    L'option -e indique que ce qui suit entre quote est le traitement à appliquer entre la lecture de la ligne et son affichage.
    Explication du traitement :

    if (/30076/ && /2019/) signifie "si la ligne contient 64510 et 2002"

    substr($_,4,6)="201104" remplace le contenu de $_ (qui contient la ligne) à partir de la position 5 (4 compté à partir de 0) et sur 6 caractères par 201104. Comme cette commande est suivie du if précédent, ça ne fait la manipulation que si la condition est remplie (si la ligne contient 30076 et 2019).

    J'ai modifié le critère de recherche car dans ton exemple, il n'y avait pas de ligne avec 30076 et 2019... donc j'ai pris 64510 et 2002 :

    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
    $ cat test
    1LCEPTFDAI20110401
    5DAI2011031010228096280229814527800200000000010310.11+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030210228096280229814859500200000000007599.73+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030810228096280264510010200200000000001282.85+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011031010228096280264510010200200000000001861.76+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030810228096280264510022600200000000005287.81+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030910228096280264510022600200000000026842.73+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030410228096280264510032300200000000003038.07+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030810228096280264510085400200000000098065.06+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011031010228096280264510091900200000000001480.66+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011031010228096280264510091900200000000011098.14+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030310228096280264510098600200000000005447.84+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    $ perl -ple 'substr($_,4,6)="201104" if (/64510/ && /2002/);' test > test2
    $ diff test test2
    6c6
    < 5DAI2011030810228096280264510010200200000000001282.85+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    ---
    > 5DAI2011040810228096280264510010200200000000001282.85+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    8c8
    < 5DAI2011031010228096280264510010200200000000001861.76+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    ---
    > 5DAI2011041010228096280264510010200200000000001861.76+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    $ cat test2
    1LCEPTFDAI20110401
    5DAI2011031010228096280229814527800200000000010310.11+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030210228096280229814859500200000000007599.73+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011040810228096280264510010200200000000001282.85+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011041010228096280264510010200200000000001861.76+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030810228096280264510022600200000000005287.81+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030910228096280264510022600200000000026842.73+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030410228096280264510032300200000000003038.07+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030810228096280264510085400200000000098065.06+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011031010228096280264510091900200000000001480.66+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011031010228096280264510091900200000000011098.14+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61
    5DAI2011030310228096280264510098600200000000005447.84+850CREDIT DES REMISES A L'ENTREE 072ESCOMPTE EFFETS COMMERCE
    00030CR61

  12. #12
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    Oui j'ai modifié par la suite une des lignes car les données étaient fausses.

    En tout cas tu as parfaitement compris ce que je souhaite faire.

    Tu n'as pas d'autres moyens que le Perl. Ca m'est interdit ...

  13. #13
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    En awk alors ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{if (/64510/ && /2002/) { $0 = substr($0,1,4) "201104" substr($0,11) } print}' test > test3
    explication :

    if (/64510/ && /2002/) idem que perl

    $0 = substr($0,1,4) "201104" substr($0,11) on modifie $0 qui contient la ligne complète en prenant les 4 premiers caractères, concaténés à 201104 puis la fin de la ligne depuis le caractère 11

  14. #14
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    Est-ce que cela donnerait un shell tel que celui-ci :

    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
    #!/bin/ksh
    liste=lst_fic_so.txt
    idmois=$1
    ficlog=extract.log
    if [ $# -ne 1 ]
    then
            echo "Indiquer la date (YYYYMM) en parametre." | tee -a ${ficlog}
            exit 1
    fi
    #echo "Mois param : " $idmois
     
    for fic in `cat ${liste}`
    do
            nomfic=`echo ${fic} | cut -f1 -d.`
            ficold=$(date +%Y%m%d%H%M)_${nomfic}.old
            cp $fic $ficold
            fictmp=${nomfic}.tmp
            rm -f ${fictmp}
            sed -nr '/(30076.*2019)|(10468.*2240)|(10468.*2240)|(10468.*2245)|(10468.*2246)|(10468.*2247)/p' $fic > $fictmp
     
            awk '{$0=substr($0,1,4) "$idmois" substr($0,11)} print}' $fictmp > $fic
            rm -f ${fictmp}
            echo "Sauvegarde de l'ancien fichier  --> ${ficold}" | tee -a ${ficlog}
            echo "Creation du nouveau fichier --> ${fic}" | tee -a ${ficlog}
    done
    Résultat :

    sed: illegal option -- r
    awk: syntax error near line 1
    awk: bailing out near line 1
    Sauvegarde de l'ancien fichier --> 201105111602_DAIDWR.old
    Creation du nouveau fichier --> DAIDWR.txt
    sed: illegal option -- r
    awk: syntax error near line 1
    awk: bailing out near line 1
    Sauvegarde de l'ancien fichier --> 201105111602_PTFDWR.old
    Creation du nouveau fichier --> PTFDWR.txt
    sed: illegal option -- r
    awk: syntax error near line 1
    awk: bailing out near line 1
    Sauvegarde de l'ancien fichier --> 201105111602_CHQTLAB-extract.old
    Creation du nouveau fichier --> CHQTLAB-extract.txt

  15. #15
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    1) Il vaut mieux tester la présence de paramètre avant de faire l'association:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if [ $# -ne 1 ]
    then
    echo "Indiquer la date (YYYYMM) en parametre." | tee -a ${ficlog}
    exit 1
    fi
    idmois=$1
    2) Il faut éviter les for ... in `cat ...`, préférer l'utilisation de read :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for fic in `cat ${liste}`
    ...
    done
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while read fic
    ...
    done < $liste
    3) awk permet de faire grosso modo la même chose que sed (avec plus d'options), donc pas la peine de multiplier les appels à sed + awk dans un script

    4) pas la peine non plus de multiplier les fichiers si ça n'est pas indispensable

    En partant de ces différents points, et en supposant qu'il n'est pas non plus indispensables de supprimer l'extension de tes fichiers de départs pour les remplacer par un .old (ce qui est risqué si tu as 2 fichiers de même nom mais d'extension différente), voici un script qui devrait marcher :

    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
    #!/bin/ksh
    liste=lst_fic_so.txt
    if [ $# -ne 1 ]
    then
            echo "Indiquer la date (YYYYMM) en parametre."
            exit 1
    fi
    idmois=$1
     
    while read fic
    do
            ficold=$(date +%Y%m%d%H%M)_${fic}.old
            mv $fic $ficold
            awk '{if (/30076.*2019/ || /10468.*2240/ || /1010.*8096/) {$0=substr($0,1,4) "'$idmois'" substr($0,11)} print}' $ficold > $fic
    done < lst_fic_so.txt
    J'ai modifié la boucle sur les fichiers. Je commence par renommer le fichier en <date>_fichier.old.
    Ensuite, je lance la commande awk sur le fichier renommé en redirigeant la sortie vers le fichier d'origine.
    Dans l'exemple ci-dessus, je n'ai recopié que 2 des 6 critères que tu avais mis dans ton sed, et j'en ai mis un 3ème pour passer sur mes fichiers de test. Tu devrais pouvoir rajouter les critères dont tu as besoin

    Edit : en plus, tes critères peuvent être simplifiés (il y a un doublon, et les 4 derniers sont presque tous identiques à 1 chiffre prêt) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (30076.*2019)|<s>(10468.*2240)|</s>(10468.*2240)|(10468.*2245)|(10468.*2246)|(10468.*2247)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (30076.*2019)|(10468.*224[0567])

  16. #16
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    Je vais tester cela ce matin et vous tiens au courant.
    Merci encore pour votre aide.

    J'ai cela en résultat :

    awk: syntax error near line 1
    awk: illegal statement near line 1
    awk: bailing out near line 1
    awk: syntax error near line 1
    awk: illegal statement near line 1
    awk: bailing out near line 1
    awk: syntax error near line 1
    awk: illegal statement near line 1
    awk: bailing out near line 1
    Sauvegarde de l'ancien fichier --> 201105120955_CHQTLAB-extract.old
    Creation du nouveau fichier -->

  17. #17
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    Maintenant je n'ai plus d'erreur car j'ai utilisé nawk au lieu de awk.
    Mais aucun filtre ne se fait.

    Voici le script :
    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
    #!/bin/ksh
    liste=lst_fic_so.txt
    ficlog=extract.log
    if [ $# -ne 1 ]
    then
            echo "Indiquer la date (YYYYMM) en parametre."
            exit 1
    fi
    idmois=$1
    while read fic
    do
            nomfic=`echo ${fic} | cut -f1 -d.`
            echo ${nomfic}
            ficold=$(date +%Y%m%d%H%M)_${nomfic}.old
            cp $fic $ficold
            cat /dev/null > $fic
            nawk '{if (/30076.*2019/ || /10468.*224[0567]/) {$0=substr($0,1,4) $idmois substr($0,11)} print }' $ficold > $fic
            echo "Sauvegarde de l'ancien fichier  --> ${ficold}" | tee -a ${ficlog}
            echo "Creation du nouveau fichier --> ${fic}" | tee -a ${ficlog}
    done < $liste

  18. #18
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    la commande doit-être ainsi avec notre awk :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nawk '{if (/30076.*2019/ || /10468.*224[0567]/) {print substr($0,1,4) ${idmois} substr($0,11)} }' $ficold > $fic
    Seul hic c'est que :
    Le filtre fonctionne uniquement si je ne mets pas la commande substr($0,1,4) ${idmois} substr($0,11)

    il n'a pas l'air de reconnaitre idmois dans cette commande awk.

  19. #19
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Citation Envoyé par patgabjoe Voir le message
    Seul hic c'est que :
    Le filtre fonctionne uniquement si je ne mets pas le commande substr($0,1,4) ${idmois} substr($0,11)

    il n'a pas l'air de reconnaitre idmois dans cette commande awk.
    Normal entre quote simple la variable ne peut être interprétée ;(

    Soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nawk '{if (/30076.*2019/ || /10468.*224[0567]/) {print substr($0,1,4) '"${idmois}"' substr($0,11)} }' $ficold > $fic
    Soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nawk -v IDMOIS=${idmois} '{if (/30076.*2019/ || /10468.*224[0567]/) {print substr($0,1,4) IDMOIS substr($0,11)} }' $ficold > $fic

  20. #20
    Membre actif
    Inscrit en
    Février 2008
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 107
    Par défaut
    Exact.
    C'est ce que j'avais réalisé par la suite.
    Il fallait donc utiliser une variable et puis Nickel.

    J'avais une autre question mais là c'est pour compresser mes fichiers qui sont dans ma liste car sinon notre filesystem sera plein.

    Peut-être dois-je ouvrir un autre sujet ?

    En tout cas merci à tous pour cette aide.
    Ciao.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Meilleur méthode pour stocker mes données
    Par cyberlewis dans le forum Windows
    Réponses: 6
    Dernier message: 03/07/2004, 11h53
  2. Réponses: 3
    Dernier message: 24/06/2004, 11h23
  3. [C#] Une seule méthode pour plusieurs composants
    Par niPrM dans le forum Windows Forms
    Réponses: 8
    Dernier message: 01/06/2004, 14h41
  4. [SWING][THREAD]Méthodes pour afficher une Frame
    Par pompidouwa dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 05/05/2004, 10h35
  5. Fonction/méthode pour obtenir l'IP de la machine
    Par sirex007 dans le forum Web & réseau
    Réponses: 3
    Dernier message: 10/04/2003, 14h36

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