Pregunta

Si tuviera una cadena con comas escapado, así:

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

¿Cómo puede usar awk para analizar esto en los siguientes artículos?

a
b
{c\,d\,e}
f
g
¿Fue útil?

Solución

{
   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. Dividir en array a, utilizando ',' como delimitador
  2. Build array b de a, líneas fusionadas que terminan en '\'
  3. Imprimir gama b (Nota: Se inicia a las 2 desde el primer elemento está en blanco)

Esta solución presume (por ahora) que ',' es el único personaje que nunca se escapó con '\' - es decir, no hay necesidad de manejar cualquier \\ en la entrada, ni combinaciones extrañas tales como \\\,\\,\\\\,,\,.

Otros consejos

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

No creo que awk tiene ningún soporte integrado para algo como esto. He aquí una solución que no es casi tan corto como de DigitalRoss, pero no debe tener ningún peligro de que cada vez que golpea accidentalmente la cadena maquillada (! Q!). Ya que pone a prueba con una if, también se puede extender a tener cuidado acerca de si realmente se ha \\, al final de la cadena, que debe ser una barra escapado, no coma.

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")
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top