Suchen Sie nach Zeilen, die eine bestimmte Länge überschreiten

Suchen Sie nach Zeilen, die eine bestimmte Länge überschreiten

Ist es möglich, in einer Datei Zeilen zu finden, die länger als 79 Zeichen sind?

Antwort1

In der Reihenfolge abnehmender Geschwindigkeit (auf einem GNU-System in einem UTF-8-Gebietsschema und bei ASCII-Eingabe) gemäß meinen Tests:

grep '.\{80\}' file

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

awk 'length>79' file

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

Außer bei der perl¹-Implementierung (oder bei awk/ grep/ sed-Implementierungen (wie mawkoder busybox), die keine Multibyte-Zeichen unterstützen), wird die Länge als Anzahl vonFiguren(je nach LC_CTYPEEinstellung des Gebietsschemas) anstelle vonBytes.

Wenn die Eingabe Bytes enthält, die nicht zu den gültigen Zeichen gehören (was manchmal vorkommt, wenn der Zeichensatz des Gebietsschemas UTF-8 ist und die Eingabe eine andere Kodierung aufweist), werden diese Bytes, je nach Lösung und Toolimplementierung, entweder als 1 Zeichen, 0 oder als keine Übereinstimmung gezählt ..

Beispielsweise würde eine Zeile, die aus 30 asa 0x80 Bytes, 30 bs, einem 0x81 Byte und 30 UTF-8 és (codiert als 0xc3 0xa9) besteht, in einem UTF-8-Gebietsschema nicht .\{80\}mit GNU grep/ übereinstimmen sed(da dieses eigenständige 0x80 Byte nicht mit übereinstimmt .) und hätte eine Länge von 30+1+30+1+2*30=122 mit perloder mawk, 3*30=90 mit gawk.

Wenn Sie in Bytes zählen möchten, legen Sie das Gebietsschema mit Cfest LC_ALL=C grep/awk/sed....

Das würde bedeuten, dass alle 4 Lösungen berücksichtigen, dass die obige Zeile 122 Zeichen enthält. Außer in perlGNU-Tools hätten Sie immer noch potenzielle Probleme mit Zeilen, die NUL-Zeichen (0x0 Byte) enthalten.


¹ Das Verhalten kann jedoch durch die Umgebungsvariable perlbeeinflusst werdenPERL_UNICODE

Antwort2

Shell-Ansatz:

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

Python-Ansatz:

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

Oder als kurzes Skript zur besseren Lesbarkeit:

#!/usr/bin/env python
import sys

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

Wenn wir Zeilenumbruchzeichen \nvon Berechnungen ausschließen möchten, können wir if len(line) > 79Folgendes tun:if len(line.strip()) > 79

Randbemerkung: Dies ist die Syntax von Python 2.7. print()Für Python 3 verwenden

verwandte Informationen