簡體   English   中英

Perl / Sed命令多次替換相同的模式

[英]Perl/Sed command to replace same pattern multiple times

我需要使用perl或sed等命令在/etc/xinetd.d/chargen設置disable=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         = 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 = no替換disable = yes而不匹配service chargen但是我需要在/etc/xinetd.conf使用相同的sed / perl命令來替換其他服務。

更新正如Jonathan在評論中強調的那樣,禁用可以位於花括號內的任何位置。

使用sed ,您可以使用:

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

第一部分搜索從一個起始service chargen到第一行的行的范圍,然后以}開頭; 在該范圍內時,它查找包含線disable = yes與之間的空間任意數disable= yes ,和改變yesno 如果有必要,你可以使正則表達式更繁瑣(沒有尾隨空格;不編輯service chargen2018塊,要求}沒有尾隨空白等)但它可能沒有必要。

您通常可以進行就地編輯,但要注意系統之間在如何執行此操作的語義上的差異。 (BSD和macOS需要-i '' ; GNU只需要-i ;兩者都接受-i.bak ,兩者意味着相同 - 但你有一個備份文件要清理。)

您可以使用此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演示

\\K重置報告的匹配的起點。 最終匹配中不再包含任何先前消費的字符

awk好嗎?:

$ 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 *=/ )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM