¿Cómo eliminar todas las líneas de un archivo de texto que tengan menos de "x" caracteres?

¿Cómo eliminar todas las líneas de un archivo de texto que tengan menos de "x" caracteres?

¿Cómo puedo eliminar todas las líneas de un archivo de texto que tengan menos de 'x' letras O números O símbolos? No puedo usarlo awk 'length($0)>'porque incluirá espacios.

Respuesta1

Suponiendo que desea eliminar líneas que contienen menos nsímbolos gráficos:

awk -v n=5 '{ line = $0; gsub("[^[:graph:]]", "") } length >= n { print line }'

Esto elimina todos los caracteres que no coinciden [[:graph:]]. Si la longitud de la cadena que queda es mayor o igual a n, se imprime la línea (sin modificar).

El valor de nse proporciona en la línea de comando.

[[:graph:]]es equivalente a [[:alnum:][:punct:]], que a su vez es lo mismo que [[:alpha:][:digit:][:punct:]]. Es más o menos lo mismo que [[:print:]]los espacios, pero no coincide.

En lugar de [^[:graph:]], podrías utilizarlo [[:blank:]]para eliminar todas las pestañas o espacios.

Con sed, siguiendo el awkcódigo anterior casi literalmente,

sed -e 'h; s/[^[:graph:]]//g' \
    -e '/.\{5\}/!d; g'

o, simplificado (solo contando caracteres que no estén en blanco),

sed -e 'h; s/[[:blank:]]//g' \
    -e '/...../!d; g'

Esto primero guarda la línea actual en el espacio de espera con h. Luego elimina todos los caracteres que no son gráficos (o caracteres en blanco en la segunda variación) en la línea con s///g. Si la línea contiene menos de 5 caracteres (cámbielo al número que desee o cambie el número de puntos en la segunda variación), la línea se elimina. De lo contrario, la línea almacenada se recupera del espacio de retención gy se imprime (implícitamente).

Respuesta2

sed -e 's/[^[:space:][:cntrl:]]/&/20' -e t -e d < file

imprimiría las líneas fileque contienen al menos 20 caracteres que no son espacios en blanco y que no son de control (consulte también [[:graph:]]o [[:alnum:][:punct:]], no está claro qué caracteres desea incluir/excluir de su descripción; tenga en cuenta que en algunos sistemas, el carácter sin espacios está incluido graphy no en space).

La idea es que intenta sustituir la aparición número 20 de un carácter de control/que no es un espacio en blanco por sí mismo ( &) y nos bifurcamos si esa sustitución tiene éxito ( t), omitiendo así la dacción (eliminar).

Con awk, podrías hacer:

awk 'gsub(/[^[:space:][:cntrl:]]/, "&") >= 20' < file

Confiando en que gsub()devuelve el número de sustituciones que ha realizado.

Con grep:

grep -E '^([[:space:][:cntrl:]]*[^[:space:][:cntrl:]]){20}' <  file

( (.*[^[:space:][:cntrl:]]){20}también funcionaría pero sería más caro).

Respuesta3

Esto eliminará las líneas que tengan entre 10 y menos de 10 caracteres:

sed -E '/^.{1,11}$/d' filename

O

sed -r '/^.{1,11}$/d' filename  

Si deseas recortar espacios puedes utilizar:

sed -E 's/^[[:space:]]*//g;s/[[:space:]]*$//g;/^.{1,11}$/d' filename

Si desea eliminar el uso en el lugar (directamente dentro del archivo)-iopción con él.

Respuesta4

Usando Raku (de soltera Perl6)

raku -ne '.put if chars( S:g/\s// ) >= 10;'  filename

o

raku -ne '.put unless chars( S:g/\s// ) < 10;'  filename

o

raku -ne '.put unless chars( S:g/\W// ) < 10;'  filename

o

raku -ne '.put unless chars( S:g/<ws>// ) < 10;'  filename

Brevemente, en Raku/Perl6 el operador "S mayúscula" S///se usa para generar una cadena resultante sin caracteres no deseados (por ejemplo, espacios en blanco), los caracteres de la cadena resultante se cuentan con la charsfunción, en comparación con "n" (usando 10 como ejemplo), y finalmente, si se cumple el valor booleano, .putdevolverá la línea original intacta.

Nota 1: "S/// usa la misma semántica que el operador s///, excepto que deja la cadena original intacta y devuelve la cadena resultante en lugar de $/ ($/ aún se establece en los mismos valores que con s///) ".

https://docs.raku.org/language/regexes#S///_non-destructive_substitution

Nota 2: En Raku/Perl6, los modificadores de expresiones regulares como :g(para 'global') se conocen como adverbios y (normalmente) se colocan al principio del operador S///or s///, justo después de Sor s.

Nota 3: El .punto en Raku/Perl6 se usa para llamar a un método en la variable de tema $_, por lo tanto, la primera 'palabra' del código .putes esencialmente una abreviatura de $_.put.

https://docs.raku.org/language/5to6-nutshell#-%3E_Method_calls

Nota 4: Raku/Perl6 tiene un conjunto mucho más restringido de indicadores de línea de comando. La -ebandera ("ejecutar") ejecuta código Raku/Perl6 en la línea de comando. La -nbandera ejecuta el código Raku/Perl6 en línea, es decir, contra cada línea de un archivo de entrada, una línea a la vez, devolviendo un resultado. Las dos banderas pueden combinarse en una -nebandera, pero de todos modos, la -ebandera debe ser la última.

Enlaces Perl_6:
https://docs.raku.org/language/5to6-nutshell#Command-line_flags
https://github.com/rakudo/rakudo/wiki/Running-rakudo-from-the-command-line

información relacionada