Все ПЦР по своей природе являются летучими. Единственный способ «навсегда» записать значение в один — настроить процесс загрузки для выполнения записи при каждой загрузке.
Очевидно, awk
был бы лучшим инструментом для этого варианта использования -, но в OP указано sed
.
Используя GNU sed
, возможны многие решения. Вот тот, который использует пространство удержания:
$ cat -A file
Hello hi 123$
if a equals b$
you$
one abc two three four$
dany uri four 123$
one two three four$
five six ^Iseven eight $
$ sed -e 'h; s/^\s*//; s/\s*$//' -nre '/^\w+(\W+\w+){3}$/{g;p}' file
if a equals b
dany uri four 123
one two three four
five six seven eight
$
Эту команду sed
можно упростить до:
$ sed -nr '/^\s*(\w+)(\W+\w+){3}\s*$/p' file
Вот еще одна более переносимая версия предыдущей команды sed
, которая использует классы символов POSIX и -E
вместо-r
:
$ sed -En '/^[[:blank:]]*[[:alnum:]]+([[:blank:]]+[[:alnum:]]+){3}[[:blank:]]*$/p' file
С помощью bash во время чтения:
set -o noglob
while IFS= read -r line
do
set -- $line
[ $# -eq 4 ] && echo "$line"
done < file
$#
:количество аргументов.
Используя GNU sed
, мы создаем регулярное выражение, которое просматривает необязательный начальный пробел (s ), за которым следуют ровно 4 пары непробельных символов (s )+ пробел (s ), за которыми следует конец пространства шаблона.
$ sed -nE 'G;/^\s*(\S+\s+){4}$/P' F1
Как вариант,
sed -nE '
s/\S+/&/4;T # 3 or less chunks
s//&/5;t # 5 or more chunks
p # exactly 4 chunks
' F1
sed -E '
s/\S+/&/5; td # 5 or more chunks
s//&/4; t # exactly 4 chunks
:d;d # 3 or less or 5 or more
' F1