Если вы квалифицируете слово для обозначения любой последовательности из 1 или более непустых символов, тогда ответ определенно да, и это тоже очень просто сделать. Это потому, что [[:blank:]]*и [^[:blank:]]*являются логическими дополнениями и - при условии, что все символы в строке полны - [[:blank:]]*U [^[:blank:]]*может описать любую возможную строку почти так же, как это .*делает.
Если в строке существует неполный символ или иным образом недопустимая последовательность байтов, то ни один из них не может успешно описать ее с начала до конца - что иногда может происходить при интерпретации строки в неправильной кодировке. Чтобы обеспечить полный символ на байт в любой строке, локаль C может быть принудительно настроена следующим образом:
LC_ALL=C sed ...
... что позволит избежать любых проблем, описывающих строку от головы до хвоста с помощью всеобъемлющего шаблона, такого как .*или([ ]*[^ ]*)*
Полностью дополняющий образец может повторять столько раз, сколько необходимо, слева направо, длину любой строки, чтобы попасть в последний возможный случай без какого-либо разрыва в шаблоне. Это, безусловно, обычный язык.
BRE:
sed 's/\(\([^[:blank:]]*\)[[:blank:]]*\)*/\2/'
ERE:
sed -E 's/(([^[:blank:]]*)[[:blank:]]*)*/\2/'
Обе эти версии будут по-прежнему печатать пустые строки, и это потому, что *звезда Клини соответствует нулю или большему количеству вхождений шаблона. Сначала он сопоставляет ноль или более непустых символов, затем ноль или более пустых символов, затем ноль или более вхождений сгруппированных совпадений до тех пор, пока не найдет строку полностью.
Сопоставив все это, волшебство происходит при замене - ссылки возвращаются группами \1и \2являются последними вхождениями каждого. Таким образом, когда замена сделана, вся строка заменяется только последним вхождением в строке, состоящей из нуля или более, не пустых символов - или подгруппы \2.
Конечно, это работает для любой возможной строки - даже пустой - что означает, что обе формы будут печатать символы новой строки для строк, которые содержат только пустые символы или вообще не содержат символов. Чтобы справиться с этим, есть пара вещей, которые вы можете сделать, но сначала давайте немного упростим ввод класса символов:
b='[:blank:]'
Теперь для печати, только если строка содержит один или несколько непустых символов, вы можете сделать:
BRE:
sed -n "s/\(\([^$b]*\)[$b]*\)*/\2/;/./p"
ERE:
sed -En "/[^$b]/s/(([^$b]*)[$b]*)*/\2/p"
- Случай BRE - замена всегда выполняется, и печатаются только пробелы с хотя бы одним оставшимся символом.
- ERE case - попытка замещения предпринимается только в пространстве шаблона, содержащем хотя бы один непустой символ.
Любая форма будет работать с любым методом - до тех пор, пока синтаксис правильный.
-nПереключатель отключает автоматический печати из шаблона, и pфлаг в s///ubstitution или /адресных /команд выдает его результаты только в случае успеха.
Эту же логику можно применять для получения любого {num}вхождения, например:
BRE:
sed -n "s/\([$b]*\([^$b]\{1,\}\)\)\{num\}.*/\2/p"
ERE:
sed -En "s/([$b]*([^$b]+)){num}.*/\2/p"
... где numв обоих регулярных выражениях можно заменить число, чтобы вывести только {num}указанное вхождение последовательности непустых символов. Здесь используется немного другая форма, чтобы гарантировать, что счетчик не смещен для начального пробела в строке.
Обратите внимание , что -Eпереключатель ERE к sedподдерживаются как в BSD и GNU версии, хотя это не является еще POSIX стандартного синтаксиса.
sed?