Основные проблемы здесь связаны с использованием сокращенных обозначений \w
и \s
. Если редактор представляет собой традиционную реализациюvi
(оригинальных исходников Билла Джоя ), то можно дополнительно установить параметр magic
, который установлен по умолчанию в большинстве современных реализаций vi
.. Это делается с помощью :set magic
.
vi
не понимает \w
и \s
и аналогичную сокращенную запись для различных классов символов, как vim
.
Чтобы выполнить замену в vi
, используйте
:%s/^\(group[ ][ ]*\)[0-9A-Za-z_]/\1Test/
Согласно документации vim
, \w
соответствует [0-9A-Za-z_]
, а \s
является пробелом или табуляцией (в [ ]
выше есть пробел и табуляция ).
Шаблон E+
, где E
— некоторое выражение, может быть заменен на EE*
.
\1
в замещающей части подстановки должно работать вvi
(любойvi
). Если это не так, попробуйтеnvi
("новый vi
" )или посмотрите, сможете ли вы установить vim
.
Исходный vi
(, упакованный как traditional-vi
по крайней мере в некоторых системах BSD ), должен иметь свои «специальные символы» (, за исключением экранированных ^
и $
), например \*
и \.
. ] и т. д. Кроме того, вы можете установить параметр magic
с помощью :set magic
(. Обычно это значение по умолчанию в современных vi
реализациях ).
Вышеуказанная замена заменит все вхождения (, например)
group 1
с
group Test
Еще один способ сделать то же самое, что и вы:
:g/^group/s/[0-9A-Za-z_]$/Test/
или просто
:g/^group/s/.$/Test/
если вам не нужно быть слишком осторожным с последним символом в строке.
Если вы хотите заменить последнее слово (, а не только последний символ )в строке:
:g/^group/s/[^ ]*$/Test/
В традиционном vi
без установленного параметра magic
это, возможно, придется написать
:g/^group/s/\[^ ]\*$/Test/
Почти никогда не бывает веских причин передавать grep
в awk
. awk
может выполнять сопоставление с образцом самостоятельно - вместо этого попробуйте awk '/not/ {print $2}'
.
Также нет необходимости передавать awk в другой awk. Здесь вам просто нужно указать набор разделителей полей (пробел и .
) вместо пробела по умолчанию в качестве разделителя:
awk -F'[ .]' '/not/ {print $2}'
A for
цикл вокруг cat
только для echo
содержимое каждой строки также бессмысленно. На самом деле, хуже, чем бессмысленно - это медленно, неэффективно и подвергает каждую строку стандартному разбиению слов оболочки (это не проблема с этим конкретным вводом, но потенциальная проблема, если вы считаете, что это хороший метод, и используете его во входных файлах, где строки может содержать пробелы и т. д.). Просто используйте cat
.
Но здесь даже не нужно использовать cat
. tee
копирует stdin как в файл, так и в stdout — т. е. это как причудливая версия cat
, которая также копирует свой ввод в файл.
Используя tee
, как указано в ответе αғsнιη, весь ваш однострочник можно сократить до:
for i in {1..255} ; do "host 10.1.9.$i" ; done |
awk -F'[ .]' '/not/ {print $2}' |
tee /tmp/flix
Потому что вы перенаправляете его только в файл. если вы хотите передать его следующей команде, используйте tee
, чтобы сделать и то, и другое.
... | tee /tmp/filx |...
tee
используется для записи в файл и передачи стандартного вывода следующей команде через |
для чтения из стандартного ввода.
Или вы должны заменить в этой части команды /tmp/filx |
, |
на ;
или &&
.