Cuente el número de líneas en blanco al final del archivo

Cuente el número de líneas en blanco al final del archivo

Tengo un archivo con líneas en blanco al final del archivo. ¿Puedo utilizar greppara contar el número de líneas en blanco al final del archivo con el nombre del archivo pasado como variable en el script?

Respuesta1

Si las líneas en blanco sonsoloal final

grep  -c '^$' myFile

o:

grep -cx '' myFile

Respuesta2

Sólo por diversión, algo espeluznante sed:

#!/bin/sh
sed '/./!H;//h;$!d;//d;x;s/\n//' "$1" | wc -l

Explicación:

  • /./aborda líneas con cualquier carácter, por lo que /./!aborda líneas vacías (como /^$/, pero quiero reutilizar el patrón opuesto); para esos, el Hcomando los agrega al espacio de espera. Así, si por cada línea vacía hemos añadido una línea al espacio de espera, siempre habrá una línea más que el número de líneas vacías. Nos ocuparemos de eso más tarde.
  • //hel patrón vacío coincide con la última expresión regular, que era cualquier carácter, por lo que se aborda cualquier línea que no esté vacía ymovidoal espacio de retención mediante el hcomando para "restablecer" las líneas recopiladas a 1. Cuando se agregue la siguiente línea vacía, habrá dos nuevamente, como se esperaba.
  • $!ddetiene el script sin salida para todas las líneas excepto la última, por lo que los comandos adicionales solo se ejecutan después de la última línea. Entonces, las líneas vacías que recopilamos en el espacio de espera están al final del archivo. Bien.
  • //d: El dcomando se ejecuta nuevamente solo para líneas que no estén vacías. Entonces, si la última línea no estaba vacía, sedsaldrá sin ningún resultado. Líneas cero. Bien.
  • xlos intercambios contienen espacio y espacio de patrón, por lo que las líneas recopiladas ahora están en el espacio de patrón para ser procesadas.
  • Pero recordamos que hay una línea de más, por lo que la reducimos eliminando una nueva línea con s/\n//.
  • ¡Voilá! El número de líneas coincide con el número de líneas vacías al final (tenga en cuenta que la primera línea no estará vacía, pero a quién le importa), por lo que podemos contarlas con wc -l.

Respuesta3

Algunas opciones más de GNU tac/ tail -r:

tac file | awk 'NF{exit};END{print NR?NR-1:0}'

O:

tac file | sed -n '/[^[:blank:]]/q;p' | wc -l

Tenga en cuenta que en la salida de:

printf 'x\n '

Es decir, cuando hay un espacio adicional después de la última línea completa (que algunos podrían considerar como una línea en blanco adicional, pero según la definición de texto POSIX, no es texto válido), darían 0.

POSIXly:

awk 'NF{n=NR};END{print NR-n}' < file

pero eso significa leer el archivo en su totalidad ( tail -r/ tacleería el archivo hacia atrás desde el final en los archivos buscables). Eso da 1como resultado la salida de printf 'x\n '.

Respuesta4

Como en realidad estás pidiendo ungrepsoluciónAgrego este confiando solo en GNU grep(vale, también usando la sintaxis de shell y echo...):

#!/bin/sh
echo $(( $(grep -c "" "$1") - $(grep -B$(grep -cv . "$1") . "$1" |grep -c "") ))

¿Qué estoy haciendo aquí? $(grep -c ".*" "$1")cuenta todas las líneas en el archivo, luego restamos el archivo sin las líneas vacías finales.

¿Y cómo conseguirlos? $(grep -B42 . "$1"agruparía todas las líneas no vacías y las 42 líneas anteriores a ellas, por lo que imprimiría todo hasta la última línea no vacía, siempre y cuando no haya más de 42 líneas vacías consecutivas antes de una línea no vacía. Para evitar ese límite, tomo $(grep -cv . "$1")como parámetro para la -Bopción, que es el número total de líneas vacías, por lo que siempre es lo suficientemente grande. De esta manera, eliminé las líneas vacías finales y puedo usarlas |grep -c ".*"para contar las líneas.

Brillante, ¿no? (-;

información relacionada