Trova eventuali righe che superano una determinata lunghezza


53

È possibile trovare delle righe in un file che superano i 79 caratteri?

Risposte:


91

In ordine decrescente di velocità (su un sistema GNU in una locale UTF-8 e su ingresso ASCII) secondo i miei test:

grep '.\{80\}' file

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

awk 'length>79' file

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

Tranne quella perl¹ (o per awk/ grep/ sedimplementazioni (like mawko busybox) che non supportano caratteri multibyte), che conta la lunghezza in termini di numero di caratteri (in base LC_CTYPEall'impostazione della locale) anziché byte .

Se ci sono byte nell'input che non fanno parte di caratteri validi (ciò accade a volte quando il set di caratteri della locale è UTF-8 e l'input è in una codifica diversa), quindi a seconda della soluzione e dell'implementazione dello strumento, quei byte conterà come 1 carattere o 0 o non corrisponderà ..

Ad esempio, una linea composta da 30 asa 0x80 byte, 30 bs, un 0x81 byte e 30 UTF-8 és (codificato come 0xc3 0xa9), in una locale UTF-8 non corrisponderebbe .\{80\}a GNU grep/ sed(in quanto tale 0x80 byte autonomo non corrisponde .), avrebbe una lunghezza di 30 + 1 + 30 + 1 + 2 * 30 = 122 con perlo mawk, 3 * 30 = 90 con gawk.

Se si desidera contare in termini di byte, correggere la locale Ccon LC_ALL=C grep/awk/sed....

Tutte le 4 soluzioni dovrebbero considerare che la riga sopra contiene 122 caratteri. Ad eccezione degli perlstrumenti GNU e, avresti ancora potenziali problemi per le righe che contengono caratteri NUL (0x0 byte).


¹ il perlcomportamento può essere influenzato dalla PERL_UNICODEvariabile d'ambiente però


Cosa intendi con "efficiente"?
Rowantran,

Penso che manatwork significhi digitare efficienza. awkpuò avvicinarsi se cadi ($0), il che è comunque implicito;).
Thor,

9
A proposito, se ancorate la regexp all'inizio della linea ^, è leggermente più veloce: ad es grep '^.\{80\}' file.
Caso

4
La soluzione perl non tiene conto della codifica di dimensioni variabili come UTF-8, a differenza di tutte le altre soluzioni.
BatchyX,

6
Valori sufficientemente grandi di N falliscono con grep ma riescono con awk. (es. grep '^.\{1000\}' fileritorna grep: invalid repetition count(s), mentre ci awk 'length>1000' fileriesce.)
mdahlman,

1

Approccio Shell:

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

Approccio 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 come una breve sceneggiatura per la leggibilità:

#!/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 volessimo escludere il carattere di nuova riga \ndai calcoli, possiamo if len(line) > 79essereif len(line.strip()) > 79

Nota a margine: questa è la sintassi di Python 2.7. Utilizzare print()per Python 3

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.