Forum Linux.débutant remplacement dans fichier

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
7
fév.
2018

bonjour à tous,

j'essaye tant bien que mal d'utiliser la fonction sed avec les regex mais j'ai un peu de mal.

j'ai un fichier avec 6 colonnes, séparateur tab. (toutes les colonnes sauf la dernière sont obligatoires).

les colonnes peuvent contenir le caractère * sauf les colonnes 2 et 5. la colonne 2 est la clef du fichier (ie jamais 2 lignes avec la même valeur en colonne 2).

voici un exemple

A test * * ici
AA test2 * * la
A uneautreclef * * la
B avantdernier * * ici
C dernier * * la

je souhaiterai remplacer le mot "ici" dans la ligne dont la colonne 2 est avantdernier par "salut".

ce qui donnerait au final:

A test * * ici
AA test2 * * la
A uneautreclef * * la
B avantdernier * * salut
C dernier * * la

je n'y arrive pas….

merci

  • # awk

    Posté par  . Évalué à 1.

    Awk permet de traiter un fichier ligne par ligne en matchant des regex ou des valeurs de champs.

    awk  '
    ($5=="ici"){print $1 "\t" $2 "\t"… "salut" }' <fichier>

    Un truc du genre devrait marcher à peu près.

    • [^] # Re: awk

      Posté par  . Évalué à 3.

      je pense que tu n'as pas pris en compte tous les paramètres de mon énoncé.
      avec awk pas de souci, je ferai un test sur $2 puis un print en remplaçant le $5 avec je que je souhaite substituer.

      dans mon cas, je souhaite utiliser sed. Cela doit être possible….

      • [^] # Re: awk

        Posté par  . Évalué à 2.

        dans mon cas, je souhaite utiliser sed. Cela doit être possible….

        Oui et non…

        Si le problème est que ton script marche pour toutes les avant-dernières lignes, sed seul ne pourra pas le faire: c'est un éditeur de ligne, pas de fichier, il est incapable de dire si une ligne est l'avant-dernière ou la première, contrairement à awk.

        En revanche, si ce que tu cherches est manipuler un modèle sur une ligne ou s'en trouve un autre, alors sed peut le faire, un exemple de réponse est donné dans un autre commentaire.

        Au cas où, je trouve ce lien plutôt utile quand je dois travailler avec du shell et que je suis bloque sur un truc.

        • [^] # Re: awk

          Posté par  . Évalué à 1.

          Si le problème est que ton script marche pour toutes les avant-dernières lignes, sed seul ne pourra pas le faire: c'est un éditeur de ligne, pas de fichier, il est incapable de dire si une ligne est l'avant-dernière ou la première, contrairement à awk.

          S'il n'avait pas dit je souhaite modifier le contenu de la 5e colonne correspondant à la clef 'avantdernier' (la clef étant la 2e colonne) mais, je souhaite modifier le contenu de la 5e colonne de l'avant dernière ligne, alors le code correspondant aurait été :

          [kangs<<azopt23a>>:0s:tmp]$ cat data.txt
          A       test    *       *       ici
          AA      test2   *       *       la
          A       uneautreclef    *       *       la
          B       avantdernier    *       *       ici
          C       dernier *       *       la
          [kangs<<azopt23a>>:0s:tmp]$ sed 'x; ${s/\(.*\t.*\t.*\t.*\t\).*/\1salut/;p;x}; 1d' data.txt
          A       test    *       *       ici
          AA      test2   *       *       la
          A       uneautreclef    *       *       la
          B       avantdernier    *       *       salut
          C       dernier *       *       la
          
        • [^] # Re: awk

          Posté par  . Évalué à 1.

          sed seul ne pourra pas le faire: c'est un éditeur de ligne

          J'avais oublié :

          SED(1)                                         User Commands                                        SED(1)
          
          
          
          NAME
                 sed - stream editor for filtering and transforming text
          
          SYNOPSIS
                 sed [OPTION]... {script-only-if-no-other-script} [input-file]...
          
          DESCRIPTION
                 Sed  is a stream editor.  A stream editor is used to perform basic text transformations on an input
                 stream (a file or input from a pipeline).  While in some ways similar to an  editor  which  permits
                 scripted  edits  (such  as  ed), sed works by making only one pass over the input(s), and is conse-
                 quently more efficient.  But it is sed's ability to filter text in a  pipeline  which  particularly
                 distinguishes it from other types of editors.
          
        • [^] # Re: awk

          Posté par  . Évalué à 3.

          Au cas où, je trouve ce lien plutôt utile quand je dois travailler avec du shell et que je suis bloque sur un truc.

          Tu voulais plutôt dire : ce lien

          • [^] # Re: awk

            Posté par  . Évalué à 2.

            En effet, oublié le http… oups.

      • [^] # Re: awk

        Posté par  . Évalué à 2.

        avec awk pas de souci, …

        Je suis navré, je croyais que tu cherchais une solution et j’ai essayé d’utiliser l’outil qui me semblait le plus adapté pour résoudre ton problème tel que je l’avais compris. Mais si le but était le défi intellectuel de le faire avec sed effectivement, j’ai répondu a côté de la plaque… tu m’en vois navré.

    • [^] # Re: awk

      Posté par  . Évalué à 2.

      On peut faire mieux, un truc du genre :

      ($5=="ici"){$5 = "salut";print $0}'

      $ echo "A B C D" | awk '{$4 = "TOTO"; print $0}'
      A B C TOTO
      
      • [^] # Re: awk

        Posté par  . Évalué à 2.

        Merci, je ne savais pas qu’on pouvait utiliser $x en lvalue.

        • [^] # Re: awk

          Posté par  . Évalué à 1.

          pas grave :)
          en tout cas, j'ai utilisé le sed donné plus bas (en modifiant legèrement car mon besoin était légèrement différent).

          merci

        • [^] # Re: awk

          Posté par  . Évalué à 3.

          C'est le truc à savoir et qui change la vie avec awk.

          Certains utilisent python pour ce genre de traitements, mais personnellement, je trouve que les regexp en python c'est pas génial (c complètement pourri mêm je trouve). Pour les regexp, ya pas mieux que shell et commandes style sed/awk/tr ou Perl.

  • # Comme ca

    Posté par  . Évalué à 1.

    [kangs<<undef>>:0s:tmp]$ cat data.txt
    A       test    *       *       ici
    AA      test2   *       *       la
    A       uneautreclef    *       *       la
    B       avantdernier    *       *       ici
    C       dernier *       *       la
    [kangs<<undef>>:0s:tmp]$ sed "s/\(.*\tavantdernier\t.*\t.*\t\).*/\1salut/" data.txt
    A       test    *       *       ici
    AA      test2   *       *       la
    A       uneautreclef    *       *       la
    B       avantdernier    *       *       salut
    C       dernier *       *       la
    

    Ajouter -i pour modifier le fichier.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.