Cómo detectar EOF en awk?

votos
8

¿Hay alguna forma de determinar si la línea actual es la última línea del flujo de entrada?

Publicado el 29/10/2009 a las 22:22
fuente por usuario
En otros idiomas...                            


11 respuestas

votos
9

El ENDpatrón especial coincidirá solo después del final de todas las entradas . Tenga en cuenta que este patrón no se puede combinar con ningún otro patrón.

Más útil es probablemente la getlinepseudo-función que se restablece $0a la siguiente línea y devuelve 1, o en el caso de EOF ¡devuelve 0! Lo cual creo que es lo que quieres

Por ejemplo:

awk '{ if(getline == 0) { print "Found EOF"} }'

Si solo procesas un archivo, esto sería equivalente:

awk 'END { print "Found EOF" }'
Respondida el 29/10/2009 a las 22:41
fuente por usuario

votos
8

Tienes dos opciones, ambas desordenadas.

  1. Almacene una copia de cada línea actual en una variable temp y luego use el bloque END para procesarla.
  2. Use el comando del sistema para ejecutar "wc -l | getline" en el bloque BEGIN para obtener el número de líneas en el archivo, y luego contar el valor.

Es posible que tenga que jugar un poco con el n. ° 2 para que funcione, pero debería funcionar. Ha pasado un tiempo desde que hice ningún awk.

Respondida el 29/10/2009 a las 22:40
fuente por usuario

votos
6

Estas son las únicas maneras sensatas para hacer lo que quiere, con el fin de mejor a peor:

awk 'NR==FNR{max++; next} FNR == max { print "Final line:",$0 }' file file

awk -v max="$(wc -l < file)" 'FNR == max { print "Final line:",$0 }' file

awk 'BEGIN{ while ( (getline dummy < ARGV[1]) > 0) max++; close(ARGV[1])} FNR == max { print "Final line:",$0 }' file
Respondida el 12/12/2012 a las 21:55
fuente por usuario

votos
4

La detección de la EOF no es demasiado fiable cuando hay varios archivos en la línea de comandos. Detectar el inicio del archivo es más fiable.

Para ello, el primer archivo es especial y que ignoran el FNR == 1.

Después de que el primer archivo y luego FNR == 1 se convierte en el final del archivo anterior. last_filename siempre tiene el nombre de archivo que se va a procesar.

Hacer su procesamiento de archivos después de la otra.

Haga su procesamiento EOF dentro del bloque de los demás, y en el bloque END.

   gawk 'BEGIN{last_filename="";} \
      FNR==1{if (last_filename==""){last_filename=FILENAME;} \
      else {print "EOF: "last_filename;last_filename=FILENAME;}} \
      END{print "END: "last_filename;}' $*

Para múltiples conjuntos de archivos, el bloque else se ejecuta al EOF para todos pero el último archivo. El último archivo se ejecuta en el bloque END.

Para los conjuntos de archivos individuales, el bloque else no se ejecuta, y se ejecuta el bloque END.

Respondida el 18/02/2014 a las 22:44
fuente por usuario

votos
2

gawk aplicación tiene la regla especial llamado ENDFILEque se desencadenó después de procesar cada archivo en la lista de argumentos. Esto funciona:

awk '{line=$0} ENDFILE {print line}' files...

más detalles se pueden encontrar aquí >>

Respondida el 13/10/2016 a las 09:18
fuente por usuario

votos
1

Una forma fácil es ejecutar el archivo a través de un intermediario sedde la escritura, que coloca un 0 en cada última línea no, y un 1 en la última.

cat input_file | sed 's/^/0/;$s/0/1/' | awk '{LST=/^1/;$0=substr($0,2)}
... your awk script in which you can use LST to check for the
... last line.'
Respondida el 06/12/2011 a las 04:17
fuente por usuario

votos
1

Para detectar la última línea de cada archivo de la lista de argumentos de la siguiente funciona muy bien:

FNR == 1 || EOF {
  print "last line (" FILENAME "): " $0
}
Respondida el 09/09/2010 a las 18:49
fuente por usuario

votos
1

Ni siquiera estoy seguro de cómo categorizar esta "solución"

{
    t = lastline
    lastline = $0
    $0 = t
}

/test/ {
    print "line <" $0 "> had a _test_"
}

END {
    # now you have "lastline", it can't be processed with the above statements
    # ...but you can work with it here
}

Lo bueno de este truco es que al asignar a $0, todos los patrones y acciones declarativos restantes funcionan, una línea se retrasa. No puedes hacer que trabajen para el END, incluso si lo pones ENDencima, pero tienes control en la última línea y no le has hecho nada más.

Respondida el 05/11/2009 a las 02:28
fuente por usuario

votos
0

Una solución portátil está proporcionado en el manual de usuario gawk , aunque como se ha mencionado en otra respuesta, gawk se ha BEGINFILE y ENDFILE.

Respondida el 02/01/2018 a las 13:55
fuente por usuario

votos
0

puede probar esto:

awk 'BEGIN{PFNR=1} FNR==PFNR{PFNR++;next} {print FILENAME,PFNR=2} END{print FILENAME}' file1 file2
Respondida el 18/02/2016 a las 05:47
fuente por usuario

votos
0

Hmm la ENDvariable awk dice cuando ya has alcanzado el EOF. Realmente no es de mucha ayuda para ti, supongo

Respondida el 29/10/2009 a las 22:27
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more