Odpowiedzi:
W kolejności malejącej prędkości (w systemie GNU w ustawieniach regionalnych UTF-8 i na wejściu ASCII) zgodnie z moimi testami:
grep '.\{80\}' file
perl -nle 'print if length$_>79' file
awk 'length>79' file
sed -n '/.\{80\}/p' file
Z wyjątkiem perl
jednej (lub implementacji awk
/ grep
/ sed
(jak mawk
lub busybox), które nie obsługują znaków wielobajtowych), która liczy długość pod względem liczby znaków (zgodnie z LC_CTYPE
ustawieniem regionalnym) zamiast bajtów .
Jeśli na wejściu znajdują się bajty, które nie stanowią części prawidłowych znaków (co zdarza się czasami, gdy zestaw znaków ustawień regionalnych to UTF-8, a dane wejściowe mają inne kodowanie), to w zależności od rozwiązania i implementacji narzędzia te bajty będzie liczony jako 1 znak lub 0 lub nie będzie pasował .
.
Na przykład linia składająca się z 30 a
bajtów 0x80, 30 b
s, bajtu 0x81 i 30 UTF-8 é
s (zakodowanych jako 0xc3 0xa9) w ustawieniach regionalnych UTF-8 nie byłaby zgodna .\{80\}
z GNU grep
/ sed
(ponieważ ten samodzielny bajt 0x80 nie pasuje .
), miałby długość 30 + 1 + 30 + 1 + 2 * 30 = 122 z perl
lub mawk
, 3 * 30 = 90 z gawk
.
Jeśli chcesz liczyć w bajtach, popraw ustawienia regionalne na za C
pomocą LC_ALL=C grep/awk/sed...
.
To znaczy, że wszystkie 4 rozwiązania uważają, że powyższy wiersz zawiera 122 znaki. Z wyjątkiem perl
narzędzi GNU i nadal możesz mieć potencjalne problemy z wierszami zawierającymi znaki NUL (bajt 0x0).
¹ na perl
zachowanie może mieć jednak wpływ PERL_UNICODE
zmienna środowiskowa
awk
może podejść bliżej, jeśli upuścisz ($0)
, co i tak jest domniemane;).
^
, jest to nieco szybsze: np grep '^.\{80\}' file
.
grep '^.\{1000\}' file
wraca grep: invalid repetition count(s)
, ale się awk 'length>1000' file
udaje.)
Podejście do powłoki:
while IFS= read -r line || [ -n "$line" ];
do
[ "${#line}" -gt 79 ] && printf "%s\n" "$line"
done < input.txt
Podejście 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
Lub jako krótki skrypt dla czytelności:
#!/usr/bin/env python
import sys
with open(sys.argv[1]) as f:
for line in f:
if len(line) > 79:
print line.strip()
Jeśli chcemy, aby wykluczyć znak nowego wiersza \n
z obliczeń, możemy if len(line) > 79
byćif len(line.strip()) > 79
Uwaga dodatkowa: jest to składnia języka Python 2.7. Użyj print()
dla Python 3