Найти все строки, превышающие определенную длину

Найти все строки, превышающие определенную длину

Можно ли найти в файле строки, длина которых превышает 79 символов?

решение1

В порядке убывания скорости (на системе GNU в локали UTF-8 и при вводе ASCII) согласно моим тестам:

grep '.\{80\}' file

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

awk 'length>79' file

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

За исключением perl¹ (или для реализаций awk/ grep/ (например , или busybox), которые не поддерживают многобайтовые символы), которые подсчитывают длину в терминах количестваsedmawkперсонажи(в соответствии с LC_CTYPEнастройками локали) вместобайты.

Если во входных данных есть байты, которые не являются частью допустимых символов (что иногда случается, когда набор символов локали — UTF-8, а входные данные имеют другую кодировку), то в зависимости от решения и реализации инструмента эти байты будут считаться либо 1 символом, либо 0, либо не будут соответствовать ..

Например, строка, состоящая из 30 aсимволов 0x80, 30 bсимволов s, байта 0x81 и 30 символов UTF-8 é(закодированных как 0xc3 0xa9), в локали UTF-8 не будет соответствовать .\{80\}GNU grep/ sed(поскольку этот отдельный байт 0x80 не соответствует .), будет иметь длину 30+1+30+1+2*30=122 с perlили mawk, 3*30=90 с gawk.

Если вы хотите вести подсчет в байтах, исправьте локаль Cна LC_ALL=C grep/awk/sed....

Это заставило бы все 4 решения учитывать, что строка выше содержит 122 символа. За исключением perlи инструментов GNU, у вас все еще будут потенциальные проблемы для строк, которые содержат символы NUL (0x0 байт).


¹ Однако perlна поведение может влиять переменная окружения.PERL_UNICODE

решение2

Подход Shell:

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

Подход 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

Или как краткий сценарий для удобства чтения:

#!/usr/bin/env python
import sys

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

Если мы хотим исключить символ новой строки \nиз вычислений, мы можем сделать if len(line) > 79этоif len(line.strip()) > 79

Примечание: это синтаксис Python 2.7. Используйте print()для Python 3

Связанный контент