Error en el comando wc para leer el número de líneas en el archivo

Error en el comando wc para leer el número de líneas en el archivo

Lo he estado usando wc -lpara verificar la cantidad de líneas que existen en mis archivos. Funcionó bien siempre pero no esta vez.

Tengo 120 archivos grandes que se supone que deben tener al menos dos líneas en cada uno de ellos. Acabo de realizar algunos trabajos de edición de texto en esos archivos para eliminar y agregar nuevas líneas. Estaba intentando verificar el número final de línea usando wc -l *como de costumbre. El resultado mostró que la mayoría de los archivos tenían solo una línea.

Abrí uno de los archivos (que según el resultado del comando mostraba que tenía solo una línea) vimy puedo ver que tenía exactamente 2 líneas. Salga vimy verifique nuevamente usando wc -l, el número de línea para ese archivo apareció como 2.

¿Alguien tiene alguna idea de lo que pasó aquí? ¿Y cómo puedo solucionar este problema en lugar de abrir los 120 archivos con vim?

PD: La última línea de mis archivos no estaba vacía.

Respuesta1

La implementación común de gnu de wcdice

'wc' cuenta el número de bytes, caracteres, palabras separadas por espacios en blanco
y nuevas líneas en cada ARCHIVO dado, o entrada estándar si no se proporciona ninguno o para un ARCHIVO de '-'.

por lo tanto, si no hay un carácter de nueva línea final en el archivo, la parte de "líneas" de la wcsalida será una menos de lo esperado. Por ejemplo, lo siguiente generará 1

printf 'hello\nworld' | wc -l 

El OP confirmó en los comentarios que vim informa la falta de la nueva línea final. Una solución simple si se sabe que todos los archivos tienen este problema es

 for f in *
 do
     echo >> "$f"
 done

para agregar una nueva línea a cada archivo.

Una forma de agregar una nueva línea condicionalmente al final de todos los archivos si falta uno es usar sed.

sed -s -i '$s/$/\n/;P;d' *

usa algunas extensiones gnu -spara tratar cada archivo por separado, -irealizar una edición en el lugar y permitir \nrepresentar una nueva línea. El programa sed en sí dice que en la última línea de cada archivo agregue una nueva línea y, para cada línea, imprima hasta la primera nueva línea y pase a la siguiente línea.

Respuesta2

Esta no es exactamente una respuesta, pero comparto una microherramienta personal que uso a menudo para normalizar archivos de texto (txtnorm):

#!/usr/bin/perl -spi
our($s);
s/\n\r|\r\n|\n|\r/\n/g;                 ## normalize \n
s/^(\xFF\xFE|\xFE\xFF|\xEF\xBB\xBF)//;  ## remove BOM !
s/(?<=.)\z/\n/;                         ## ensure newline at eof

if($s){ s/\xC2\xA0/ /g }                ## -s non breaking spaces-> " "

txtnorm *.txtnormaliza el final de línea, garantiza nuevas líneas al final, elimina las listas de materiales y (con -s) puede normalizar espacios que no se rompan.

Asegúrese de usarlo SÓLO en archivos de texto.

información relacionada