Encuentra cualquier línea que exceda cierta longitud

53

¿Es posible encontrar líneas en un archivo que superen los 79 caracteres?

rowantran
fuente

Respuestas:

91

En orden de disminución de la velocidad (en un sistema GNU en un entorno UTF-8 y en entrada ASCII) de acuerdo con mis pruebas:

grep '.\{80\}' file

perl -nle 'print if length$_>79' file

awk 'length>79' file

sed -n '/.\{80\}/p' file

Excepto para el perl¹ uno (o para awk/ grep/ sedimplementaciones (como mawku busybox) que no admiten caracteres de varios bytes), que cuenta la longitud en términos de número de caracteres (de acuerdo con la LC_CTYPEconfiguración de la configuración regional) en lugar de bytes .

Si hay bytes en la entrada que no forman parte de caracteres válidos (lo que sucede a veces cuando el juego de caracteres de la configuración regional es UTF-8 y la entrada está en una codificación diferente), entonces, dependiendo de la solución y la implementación de la herramienta, esos bytes contará como 1 carácter, o 0 o no coincidirá ..

Por ejemplo, una línea que consta de 30 asa 0x80 byte, 30 bs, 0x81 byte y 30 UTF-8 és (codificada como 0xc3 0xa9), en un entorno local UTF-8 no coincidiría .\{80\}con GNU grep/ sed(como ese byte independiente 0x80 no coincide .), tendría una longitud de 30 + 1 + 30 + 1 + 2 * 30 = 122 con perlo mawk, 3 * 30 = 90 con gawk.

Si desea contar en términos de bytes, arregle la configuración regional Ccon LC_ALL=C grep/awk/sed....

Eso tendría las 4 soluciones, considere que la línea anterior contiene 122 caracteres. Excepto en las perlherramientas GNU, aún tendría problemas potenciales para las líneas que contienen caracteres NUL (0x0 byte).


¹ el perlcomportamiento puede verse afectado por la PERL_UNICODEvariable de entorno

hombre trabajando
fuente
¿Qué quieres decir con "eficiente"?
rowantran
Creo que manatwork significa eficiencia de escritura. awkpuede acercarse si se cae ($0), lo cual está implícito de todos modos;).
Thor
99
Por cierto, si ancla la expresión regular al comienzo de la línea con ^, es un poco más rápido: por ejemplo grep '^.\{80\}' file.
cas
44
La solución perl no tiene en cuenta la codificación de tamaño variable, como UTF-8, a diferencia de todas las otras soluciones.
BatchyX
66
Valores suficientemente grandes de N fallan con grep pero tienen éxito con awk. (por ejemplo , grep '^.\{1000\}' fileregresa grep: invalid repetition count(s), mientras awk 'length>1000' filetiene éxito.)
mdahlman
1

Enfoque de Shell:

while IFS= read -r line || [ -n "$line" ];
do 
    [ "${#line}" -gt 79 ] && printf "%s\n" "$line"
done < input.txt

Enfoque de Python:

python -c 'import sys;f=open(sys.argv[1]);print "\n".join([ l.strip() for l in f if len(l) >79 ]);f.close()' input.txt

O como una secuencia de comandos breve para facilitar la lectura:

#!/usr/bin/env python
import sys

with open(sys.argv[1]) as f:
    for line in f:
        if len(line) > 79:
            print line.strip()

Si quisiéramos excluir el carácter de nueva línea \nde los cálculos, podemos hacer que if len(line) > 79seaif len(line.strip()) > 79

Nota al margen: esta es la sintaxis de Python 2.7. Uso print()para Python 3

Sergiy Kolodyazhnyy
fuente