Question

Si j'avais une chaîne avec des virgules échappées comme ceci:

a,b,{c\,d\,e},f,g

Comment pourrais-je utiliser awk pour que dans les éléments suivants?

a
b
{c\,d\,e}
f
g
Était-ce utile?

La solution

{
   split($0, a, /,/)
   j=1
   for(i=1; i<=length(a); ++i) {
      if(match(b[j], /\\$/)) {
         b[j]=b[j] "," a[i]
      } else {
         b[++j] = a[i]
      }
   }
   for(k=2; k<=length(b); ++k) {
      print b[k]
   }
}
  1. Diviser en a tableau, en utilisant ',' comme séparateur
  2. Construction b de réseau de a, lignes fusion qui se terminent par '\'
  3. array Imprimer b (Remarque: à partir de 2 depuis le premier élément est vide)

Cela suppose de solution (pour l'instant) que « , » est le seul personnage qui est jamais échappé avec « \ » - qui est, il n'y a pas besoin de gérer tout \\ dans l'entrée, ni des combinaisons étranges tels que \\\,\\,\\\\,,\,.

Autres conseils

{
  gsub("\\\\,", "!Q!")
  n = split($0, a, ",")
  for (i = 1; i <= n; ++i) {
    gsub("!Q!", "\\,", a[i])
    print a[i]
  }
}

Je ne pense pas awk a tout support intégré pour quelque chose comme ça. Voici une solution qui est loin d'être aussi courte que celle DigitalRoss, mais ne devrait avoir aucun danger de ne jamais frapper accidentellement votre chaîne maquillée (! Q!). Comme il teste avec un if, vous pouvez aussi l'étendre à faire attention à si vous avez réellement \\, à la fin de votre chaîne, qui devrait être une barre oblique échappé, et pas la virgule.

BEGIN {
    FS = ","
}

{
    curfield=1
    for (i=1; i<=NF; i++) {
        if (substr($i,length($i)) == "\\") {
            fields[curfield] = fields[curfield] substr($i,1,length($i)-1) FS
        } else {
            fields[curfield] = fields[curfield] $i
            curfield++
        }
    }
    nf = curfield - 1
    for (i=1; i<=nf; i++) {
        printf("%d: %s   ",i,fields[i])
    }
    printf("\n")
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top