Encontre quaisquer linhas que excedam um determinado comprimento

46

É possível encontrar linhas em um arquivo que excedam 79 caracteres?

    
por bladezzz 12.07.2012 / 20:21

2 respostas

74

Em ordem decrescente de velocidade (em um sistema GNU em uma localidade UTF-8 e em entrada ASCII) de acordo com meus testes:

grep '.\{80\}' file

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

awk 'length>79' file

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

Exceto para as implementações perl ((ou awk / grep / sed (como mawk ou busybox) que não suportam caracteres de vários bytes), isso conta o comprimento em termos do número de caracteres (de acordo com a configuração LC_CTYPE da localidade) em vez de bytes .

Se houver bytes na entrada que não fazem parte de caracteres válidos (o que acontece às vezes quando o conjunto de caracteres do código de idioma é UTF-8 e a entrada está em uma codificação diferente), dependendo da implementação da solução e da ferramenta , esses bytes serão contados como 1 caractere ou 0 ou não corresponderão a . .

Por exemplo, uma linha que consiste em 30 a sa 0x80 byte, 30 b s, um byte 0x81 e 30 UTF-8 é s (codificado como 0xc3 0xa9), em uma localidade UTF-8 não corresponderia a .\{80\} com GNU grep / sed (como esse byte autônomo 0x80 não corresponde a . ), teria um comprimento de 30 + 1 + 30 + 1 + 2 * 30 = 122 com perl ou mawk , 3 * 30 = 90 com gawk .

Se você quiser contar em termos de bytes, corrija a localidade para C com LC_ALL=C grep/awk/sed... .

Isso teria todas as 4 soluções considerando que a linha acima contém 122 caracteres. Exceto nas ferramentas perl e GNU, você ainda tem problemas potenciais para as linhas que contêm caracteres NUL (0x0 byte).

¹ o comportamento perl pode ser afetado pela variável de ambiente PERL_UNICODE , embora

    
por 12.07.2012 / 20:27
1

abordagem da Shell:

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

Abordagem em 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

Ou como um script curto para legibilidade:

#!/usr/bin/env python
import sys

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

Se quisermos excluir o caractere de nova linha \n dos cálculos, podemos fazer if len(line) > 79 be if len(line.strip()) > 79

Nota: esta é a sintaxe do Python 2.7. Use print() para o Python 3

    
por 03.12.2017 / 04:54