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 mawk
oder busybox), die keine Multibyte-Zeichen unterstützen), wird die Länge als Anzahl vonFiguren(je nach LC_CTYPE
Einstellung 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 a
sa 0x80 Bytes, 30 b
s, 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 perl
oder mawk
, 3*30=90 mit gawk
.
Wenn Sie in Bytes zählen möchten, legen Sie das Gebietsschema mit C
fest 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 perl
GNU-Tools hätten Sie immer noch potenzielle Probleme mit Zeilen, die NUL-Zeichen (0x0 Byte) enthalten.
¹ Das Verhalten kann jedoch durch die Umgebungsvariable perl
beeinflusst 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 \n
von Berechnungen ausschließen möchten, können wir if len(line) > 79
Folgendes tun:if len(line.strip()) > 79
Randbemerkung: Dies ist die Syntax von Python 2.7. print()
Für Python 3 verwenden