Как удалить все строки в текстовом файле, в которых меньше '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///
, сразу после S
or 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-из-командной-строки