Команда Perl / Sed для замены одного и того же шаблона несколько раз - PullRequest
0 голосов
/ 24 февраля 2019

Мне нужно установить disable=no в /etc/xinetd.d/chargen с помощью таких команд, как perl или sed.

/etc/xinetd.d/chargen содержимое:

# description: An xinetd internal service which generate characters.  The
# xinetd internal service which continuously generates characters until the
# connection is dropped.  The characters look something like this:
# !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg
# This is the tcp version. 
service chargen
{
        disable         = yes
        type            = INTERNAL
        id              = chargen-stream
        socket_type     = stream
        protocol        = tcp
        user            = root
        wait            = no 
}

# This is the udp version. 
service chargen
{
        disable         = yes
        type            = INTERNAL
        id              = chargen-dgram
        socket_type     = dgram
        protocol        = udp
        user            = root
        wait            = yes 
}

Я использовал команду perl

perl -0777 -pe 's|(service chargen[^\^]+)disable\s+=\syes|\1disable=no|' /etc/xinetd.d/chargen 
но он заменяет только одно место.
# description: An xinetd internal service which generate characters.  The
# xinetd internal service which continuously generates characters until the
# connection is dropped.  The characters look something like this:
# !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg
# This is the tcp version.
service chargen
{
        disable         = yes
        type            = INTERNAL
        id              = chargen-stream
        socket_type     = stream
        protocol        = tcp
        user            = root
        wait            = no
}

# This is the udp version.
service chargen
{
        disable=no
        type            = INTERNAL
        id              = chargen-dgram
        socket_type     = dgram
        protocol        = udp
        user            = root
        wait            = yes
}

Какая команда должна заставить его работать в обоих местах?

ПРИМЕЧАНИЕ : я мог бы заменить disable = yes на disable = no без сопоставления service chargen, но мне нужно использовать ту же команду sed / perl для замены в /etc/xinetd.conf, которая будет иметь другиеуслуги тоже.

ОБНОВЛЕНИЕ Как отметил Джонатан в своем комментарии, отключение может быть в любом месте внутри цветочной скобки.

Ответы [ 3 ]

0 голосов
/ 24 февраля 2019

Хорошо, хорошо?:

$ awk '/service chargen/,/}/{if(/disable/)sub(/yes/,"no")}1' file
...
        disable         = no
...
        disable         = no
...

Объяснено:

$ awk '                          # well, awk
/service chargen/,/}/ {          # between service chargen {...}
    if(/disable/)                # if disable found
        sub(/yes/,"no")          # replace yes with no
}1' file                         # output

Не стесняйтесь настроить регулярное выражение (/disable/) по своему вкусу (например, /^ *disable *=/).

0 голосов
/ 24 февраля 2019

Используя sed, вы можете использовать:

sed -e '/^service chargen/,/^}/ { /disable *= yes/ s/yes/no/; }'

Первая часть ищет диапазоны строк от одной начальной service chargen до первой строки, начинающейся с };в пределах этого диапазона он ищет строки, содержащие disable = yes с произвольным числом пробелов между disable и = yes, и изменяет yes на no.При необходимости вы можете сделать регулярные выражения более суетливыми (без пробела; не редактируйте блоки service chargen2018, требуйте, чтобы у } не было пробелов и т. Д.), Но это, вероятно, не нужно.

Вы можете часто выполнять редактирование на месте, но остерегайтесь различий между системами в семантике того, как вы это делаете.(BSD и macOS требуют -i ''; GNU требует только -i; оба принимают -i.bak, и это означает то же самое в обоих - но у вас есть резервный файл для очистки.)

0 голосов
/ 24 февраля 2019

Вы можете использовать эту команду perl:

perl -0777 -pe 's/(?m)^service chargen\s*\{[^}]*disable\s*=\s*\Kyes/no/g' file

# description: An xinetd internal service which generate characters.  The
# xinetd internal service which continuously generates characters until the
# connection is dropped.  The characters look something like this:
# !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg
# This is the tcp version.
service chargen
{
        disable         = no
        type            = INTERNAL
        id              = chargen-stream
        socket_type     = stream
        protocol        = tcp
        user            = root
        wait            = no
}

# This is the udp version.
service chargen
{
        disable         = no
        type            = INTERNAL
        id              = chargen-dgram
        socket_type     = dgram
        protocol        = udp
        user            = root
        wait            = yes
}

RegEx Demo

\K сбрасывает стартточка сообщенного матча.Все ранее использованные персонажи больше не включаются в финальный матч

...