Как удалить все строки в текстовом файле, содержащие меньше «x» символов?

Как удалить все строки в текстовом файле, содержащие меньше «x» символов?

Как удалить все строки в текстовом файле, в которых меньше 'x' букв ИЛИ цифр ИЛИ символов? Я не могу использовать, awk 'length($0)>'так как это будет включать пробелы.

решение1

Предположим, вы хотите удалить строки, содержащие менее nграфических символов:

awk -v n=5 '{ line = $0; gsub("[^[:graph:]]", "") } length >= n { print line }'

Это удалит все символы, которые не соответствуют [[:graph:]]. Если длина оставшейся строки больше или равна n, печатается (немодифицированная) строка.

Значение nуказывается в командной строке.

[[:graph:]]эквивалентно [[:alnum:][:punct:]], что в свою очередь то же самое, что [[:alpha:][:digit:][:punct:]]. Это примерно то же самое, что и , [[:print:]]но не соответствует пробелам.

Вместо этого [^[:graph:]]вы могли бы использовать , [[:blank:]]чтобы удалить все символы табуляции или пробелы.

С помощью sed, следуя приведенному выше awkкоду почти дословно,

sed -e 'h; s/[^[:graph:]]//g' \
    -e '/.\{5\}/!d; g'

или, упрощенно (учитываются только непустые символы),

sed -e 'h; s/[[:blank:]]//g' \
    -e '/...../!d; g'

Сначала текущая строка сохраняется в удерживаемом пространстве с помощью h. Затем она удаляет все неграфические символы (или пустые символы во втором варианте) в строке с помощью s///g. Если затем строка содержит менее 5 символов (измените это на любое желаемое число или измените количество точек во втором варианте), строка удаляется. В противном случае сохраненная строка извлекается из удерживаемого пространства с помощью gи (неявно) печатается.

решение2

sed -e 's/[^[:space:][:cntrl:]]/&/20' -e t -e d < file

выведет строки, fileсодержащие не менее 20 непробельных неуправляющих символов (см. также [[:graph:]]или [[:alnum:][:punct:]], неясно, какие символы вы хотите включить/исключить из своего описания; учтите, что в некоторых системах символ неразрывного пробела включен в , graphно не включен в space).

Идея состоит в том, что он пытается заменить 20-е вхождение непробельного/управляющего символа самим собой ( &), и мы выполняем ответвление, если эта замена успешна ( t), таким образом пропуская dдействие (удаление).

С помощью awkвы можете сделать:

awk 'gsub(/[^[:space:][:cntrl:]]/, "&") >= 20' < file

Опираясь на тот факт, что gsub()возвращает количество сделанных замен.

С grep:

grep -E '^([[:space:][:cntrl:]]*[^[:space:][:cntrl:]]){20}' <  file

( (.*[^[:space:][:cntrl:]]){20}тоже подойдет, но будет дороже).

решение3

Это удалит строки, содержащие 10 и менее 10 символов:

sed -E '/^.{1,11}$/d' filename

ИЛИ

sed -r '/^.{1,11}$/d' filename  

Если вы хотите обрезать пробелы, вы можете использовать:

sed -E 's/^[[:space:]]*//g;s/[[:space:]]*$//g;/^.{1,11}$/d' filename

Если вы хотите удалить на месте (прямо внутри файла), используйтевариант с ним.

решение4

Использование Raku (ранее Perl6)

raku -ne '.put if chars( S:g/\s// ) >= 10;'  filename

или

raku -ne '.put unless chars( S:g/\s// ) < 10;'  filename

или

raku -ne '.put unless chars( S:g/\W// ) < 10;'  filename

или

raku -ne '.put unless chars( S:g/<ws>// ) < 10;'  filename

Вкратце, в Raku/Perl6 оператор «заглавная-S» S///используется для генерации результирующей строки, свободной от нежелательных символов (например, пробелов), символы результирующей строки подсчитываются функцией chars, сравниваются с «n» (например, 10), и, наконец, если логическое значение удовлетворяется, .putвозвращается исходная строка без изменений.

Примечание 1: «S/// использует ту же семантику, что и оператор s///, за исключением того, что он оставляет исходную строку нетронутой и возвращает результирующую строку вместо $/ ($/ по-прежнему имеет те же значения, что и s///)».

https://docs.raku.org/language/regexes#S///_неразрушающая_подстановка

Примечание 2: В Raku/Perl6 модификаторы регулярных выражений, такие как :g(для «глобального»), называются наречиями и (обычно) размещаются в начале оператора S///or s///, сразу после Sor s.

Примечание 3: .Точка в Raku/Perl6 используется для вызова метода для переменной темы $_, поэтому первое «слово» кода .putпо сути является сокращением для $_.put.

https://docs.raku.org/language/5to6-nutshell#-%3E_Method_calls

Примечание 4: Raku/Perl6 имеет гораздо более ограниченный набор флагов командной строки. Флаг -e("execute") запускает код Raku/Perl6 в командной строке. Флаг -nзапускает код Raku/Perl6 построчно, т. е. по одной строке входного файла, возвращая результат. Два флага можно объединить в один -neфлаг, но в любом случае -eфлаг должен идти последним.

Ссылки Perl_6:
https://docs.raku.org/language/5to6-nutshell#Флаги_командной_строки
https://github.com/rakudo/rakudo/wiki/Запуск-rakudo-из-командной-строки

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