
Lo he estado usando wc -l
para 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) vim
y puedo ver que tenía exactamente 2 líneas. Salga vim
y 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 wc
dice
'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 wc
salida 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 -s
para tratar cada archivo por separado, -i
realizar una edición en el lugar y permitir \n
representar 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 *.txt
normaliza 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.