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 :

Utiliser sed avec deux fichiers


Sujet :

Shell et commandes GNU

  1. #1
    Membre régulier
    Homme Profil pro
    Webdesigner
    Inscrit en
    Mai 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Mai 2014
    Messages : 8
    Par défaut Utiliser sed avec deux fichiers
    Bonjour,

    J'ai un petit soucis.
    J'essaie d'utiliser sed pour insérer du texte à un endroit précis d'un fichier. Voici mon 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
    {
      "test_data": [
        {
          "id": "1",
          "pm": "30",
          "mp": "40"
        }
      ],
      "test": [
        "id",
        "pm",
        "mp"
      ]
    }
    J'aimerais insérer du texte après l’accolade de test_data. Le fichier peut contenir plus ou moins d'information. Je suis donc arriver à cette commande qui fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed "/^[[:blank:]]*\"test_data\": \[$/,/^[[:blank:]]*],*$/ {s/^[[:blank:]]*}$/&test /}" myfile
    Qui donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
      "test_data": [
        {
          "id": "1",
          "pm": "30",
          "mp": "40"
        }test
      ],
      "test": [
        "id",
        "pm",
        "mp"
      ]
    }
    Super.
    Maintenant au lieu d'ajouter du texte, j'aimerais ajouter le contenu d'un fichier à la place de test. Je suis donc parti sur quelque chose de ce genre là:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed "/^[[:blank:]]*\"test_data\": \[$/,/^[[:blank:]]*],*$/ {s/^[[:blank:]]*}$/&$(cat myAnotherFile) /}" myfile
    Non fonctionnel. J'ai donc fait des recherches, et je suis tombé sur le /r qui permet d'insérer le contenu d'un fichier.
    Mais pour être honnête, je ne sais pas comment insérer ce /r dans ma commande ci-dessus ....

    Quelqu'un a une idée ?
    Merci d'avance !
    Cordialement

  2. #2
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 982
    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 982
    Par défaut
    Je ne sais pas trop à quoi ressemble ton autre fichier, mais l'outil pour manipuler du json (ce qu'est ton fichier d'origine) est jq plutôt que sed.

  3. #3
    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,
    La commande r n'insére pas en bout de ligne mais sur une ou plusieurs lignes séparées
    Tu peux essayer comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e "/^[[:blank:]]*\"test_data\": \[$/,/^[[:blank:]]*],*$/ {/^[[:blank:]]*}$/r myAnotherFile" -e "}" myfile
    affichage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ...
          "mp": "40"
        }
    l'ajout
    ici
      ],
    ...
    Cordialement

  4. #4
    Membre régulier
    Homme Profil pro
    Webdesigner
    Inscrit en
    Mai 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Mai 2014
    Messages : 8
    Par défaut
    Bonjour !

    Merci pour ta réponse !
    Mais il n'y a pas moyen d'écrire sur la même ligne que celle de } ?

    Par exemple si mon contenu du fichier c'est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    test,
    ceci
    est
    un
    test
    Cela donnerait:

    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
    {
      "test_data": [
        {
          "id": "1",
          "pm": "30",
          "mp": "40"
        }test,
    ceci
    est
    un
    test
      ],
      "test": [
        "id",
        "pm",
        "mp"
      ]
    }
    EDIT:

    J'ai cherché une alternative en faisant un cat de mon fichier dans ma variable:

    J'affiche ensuite ma variable à la place de text dans ma commande d'origine. Malheureusement j'ai une erreur quand je fais ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed: -e expression #1, char 73: unterminated `s' command
    Et je ne comprends pas .. Car si je fais a="jjjjjjjj" et que j'affiche ma variable, cela fonctionne. Mais pas si ça contient le cat d'un fichier.

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    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 102
    Par défaut
    Citation Envoyé par Sparkk Voir le message
    Mais il n'y a pas moyen d'écrire sur la même ligne que celle de } ?
    Il semblerait que ton fichier soit au format "json", non?
    Or, ce format ne tient pas compte des espaces ni des retours à la ligne (sauf entre guillemets, bien sûr).
    Donc, afin que nous puissions comprendre ton réel besoin, peux-tu nous dire si tu as une bonne raison de vouloir absolument écrire au bout de la ligne plutôt que sur la ligne suivante?

  6. #6
    Membre régulier
    Homme Profil pro
    Webdesigner
    Inscrit en
    Mai 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Mai 2014
    Messages : 8
    Par défaut
    Salut !

    C'est mélangé en fait, il y a un peu de tout. Mais ce n'est pas vraiment du JSON. Il faut impérativement que j'insère sur la même ligne car c'est comme ça que je souhaite faire
    Du coup j'ai edit mon message.

    "

    J'ai cherché une alternative en faisant un cat de mon fichier dans ma variable:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a=$(cat file)
    sed "/^[[:blank:]]*\"testing\": \[$/,/^[[:blank:]]*],*$/ {s/^[[:blank:]]*}$/&`echo $a`/}" $1
    J'affiche ensuite ma variable à la place de text dans ma commande d'origine. Malheureusement j'ai une erreur quand je fais ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed: -e expression #1, char 73: unterminated `s' command
    Et je ne comprends pas .. Car si je fais a="jjjjjjjj" et que j'affiche ma variable, cela fonctionne. Mais pas si ça contient le cat d'un fichier.

    "

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    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 102
    Par défaut
    Citation Envoyé par Sparkk Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed: -e expression #1, char 73: unterminated `s' command
    Et je ne comprends pas .. Car si je fais a="jjjjjjjj" et que j'affiche ma variable, cela fonctionne. Mais pas si ça contient le cat d'un fichier.
    Ben, ça, c'est complètement normal!

    Si ton fichier ne contient que des lettres ou des chiffres, tu n'auras pas cette erreur, mais s'il contient des caractères interprétés par sed (comme "/" RETURN ou d'autres), l'insertion de ton fichier à l'intérieur même de la commande sed a toutes les chances de la rendre syntaxiquement incorrecte.

  8. #8
    Membre régulier
    Homme Profil pro
    Webdesigner
    Inscrit en
    Mai 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Mai 2014
    Messages : 8
    Par défaut
    Et on ne peut corriger cela ?

  9. #9
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Par défaut
    Salut, ça ne répond que partiellement à ta commande car je n'utilise pas sed, mais le résultat est là :
    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
    while IFS=$'\n' read ligne
    do
      [[ "test_data" =~ ${ligne} ]] && TestData=Oui
     
      if [[ -z ${TestData} ]]
      then
        echo "${ligne}" 
      else
        if [[ '{' =~ ${ligne} ]]
        then
          echo "}" $(<fichier2)
          unset TestData
        else
          echo "${ligne}"
        fi
      fi
    done < fichier1
    Et voilà ce que ça donne :
    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 fichier1
    {
      "test_data": [
        {
          "id": "1",
          "pm": "30",
          "mp": "40"
        }
      ],
      "test": [
        "id",
        "pm",
        "mp"
      ]
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    cat fichier2
    test,
    ceci
    est
    un
    test
    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
    while IFS=$'\n' read ligne
    do
      [[ "test_data" =~ ${ligne} ]] && TestData=Oui
     
      if [[ -z ${TestData} ]]
      then
        echo "${ligne}" 
      else
        if [[ '{' =~ ${ligne} ]]
        then
          echo "}" $(<fichier2)
          unset TestData
        else
          echo "${ligne}"
        fi
      fi
    done < fichier1
     
    {
      "test_data": [
        {
          "id": "1",
          "pm": "30",
          "mp": "40"
        }test,
    ceci
    est
    un
    test
      ],
      "test": [
        "id",
        "pm",
        "mp"
      ]
    }

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    hizoka, le motif cherché doit être à droite :ça marche peut-être, mais ce n'est pas correct.
    et il est préférable de mettre l'expression dans une variable utilisée sans guillemets.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    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 102
    Par défaut
    Citation Envoyé par Sparkk Voir le message
    Et on ne peut corriger cela ?
    Ben... suivant le contenu du fichier, ça peut être compliqué!

    Ça me paraît plus simple d'utiliser la commande d'insertion de fichier, quitte à supprimer dans une 2ème passe le "return" dont tu ne veux pas.

    Si tu es sûr qu'il existe un caractère que ton fichier ne contient pas, tu peux l'utiliser comme séparateur de "substitute".
    Par exemple, si ton fichier ne contient pas de "X", tu peux écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a=$(cat "$file")
    sed "/^[[:blank:]]*\"testing\": \[$/,/^[[:blank:]]*],*$/ {sX^[[:blank:]]*}$X&$(echo "$a")X}" $1
    ou bien, s'il ne contient pas de pipe "|":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a=$(cat "$file")
    sed "/^[[:blank:]]*\"testing\": \[$/,/^[[:blank:]]*],*$/ {s|^[[:blank:]]*}$|&$(echo "$a")|}" $1
    mais je ne sais pas si ça fonctionne avec les RETURN (je suis pas spécialiste de sed).

    Tu peux déjà faire un test avec un fichier contenant juste 2 lignes contenant "aa" et "bb", par exemple.

    L'autre possibilité est de conserver les "/" et de les quoter en insérant un backslash devant, avec quelque chose comme (en espérant qu'il y a le bon nombre de backslash! (pas testé)):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a=$(sed -e 's|/|\\/|g' -e 's|$|\\$|' "$file")
    sed "/^[[:blank:]]*\"testing\": \[$/,/^[[:blank:]]*],*$/ {s/^[[:blank:]]*}$/&$(echo "$a")/}" $1

  12. #12
    Membre régulier
    Homme Profil pro
    Webdesigner
    Inscrit en
    Mai 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Mai 2014
    Messages : 8
    Par défaut
    Ha merci tu m'as donné une idée !
    Et ça fonctionne.

    Quand je créé mon fichier dans mon script, je met un \ + un \n pour le retour à la ligne. Comme ça, je n'ai pas de soucis lorsque je souhaite print ma variable avec sed.

    Je te remercie vivement pour ton aide !

  13. #13
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 283
    Par défaut
    Bonjour

    Y a la méthode ultra-bourrine avec awk:
    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
    $ cat mixtjson.txt
    {
      "test_data": [
        {
          "id": "1",
          "pm": "30",
          "mp": "40"
        }
      ],
      "test": [
        "id",
        "pm",
        "mp"
      ]
    }
    $ awk -F'}' 'BEGIN{RS="\r";FS="}";OFS=FS;} {for (i=1;i<=NF;i++) if ($i ~ "test_data") $(i+1)="Mon texte ajouté"$(i+1);} 1' mixtjson.txt
    {
      "test_data": [
        {
          "id": "1",
          "pm": "30",
          "mp": "40"
        }Mon texte ajouté
      ],
      "test": [
        "id",
        "pm",
        "mp"
      ]
    }
    Y aura-t-il des accolades à l'intérieur de "test_data" ?

  14. #14
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 335
    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 335
    Par défaut
    Bonjour, un peu tard, mais en gnu sed, on peut faire des trucs du genre:
    Le texte que je veux insérer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ cat xx.txt 
    test,
    ceci
    est
    un
    test
    à partir de la chaine toto titi tata, je veux l'insérer juste après titi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ echo 'toto titi tata' | sed 's/\(.*\)\(titi\)\(.*\)/echo \1\2"$(cat xx.txt)"\3/e'
    toto tititest,
    ceci
    est
    un
    test tata
    La seule difficulté ici, c'est de réussir à découper la ligne entière en trois champs maximum:
    \1 => 'debut de ligne jusqu'au pattern'
    \2 => 'pattern qui nous interresse'
    \3 => 'le reste jusqu'à fin de ligne'

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 16/11/2009, 16h27
  2. Réponses: 3
    Dernier message: 24/04/2009, 09h12
  3. Réponses: 1
    Dernier message: 22/11/2008, 20h50
  4. [VB6] Utiliser MSChart avec un fichier text
    Par bandy dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 30/03/2006, 14h07
  5. Mise en réseau avec deux fichiers *.mdb
    Par Rouge_XIII dans le forum Access
    Réponses: 6
    Dernier message: 08/12/2005, 19h09

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