繁体   English   中英

提取两个字符串之间的特定字符串并列出所需的内容

[英]Extract specific string between two strings and list the required content

如何找到可用字符串的块名称?

server.conf 文件

server_pool odd {
    0:server1:yes:profile_server1:192.168.1.1,192.168.1.2;
    1:server3:yes:profile_server3:192.168.1.5,192.168.1.6;
}

server_pool even {
    0:server2:yes:profile_server2:192.168.1.3,192.168.1.4;
    1:server4:yes:profile_server4:192.168.1.7,192.168.1.8;
}

#server_pool even {
#    0:server1:yes:profile_server1:192.168.1.1,192.168.1.2;
#    1:server3:yes:profile_server3:192.168.1.5,192.168.1.6;
#}

笔记:-

  1. “server_pool”是一个静态字符串
  2. “pool_name”可以是任何没有空格的字符串
  3. "如果一行中有 # 忽略它

要求

  1. 需要通过提供的服务器主机名找到“pool_name”作为输入即 server{1,2,3,} 并将其存储在变量中

例如

如果需要查找 server1 属于哪个块/节。 在给定的用例中,它属于奇数,因此将变量存储为 POOLNAME=odd

grep -oP '^server\s\K[^ ]+|^[^#]\s+\d+:\K[^:]+' inputfile
pool0
server1
server2
pool1
server3
server4

使用awk

awk -F'[: ]+' '/}/{p=0}/^#|}/||!NF{next}/pool[0-9]+[ \t]+?{/{if(h)print "";p=1;print $2;next}p{print $3;h=1}' file

更好的可读性:

awk -F'[: ]+' '
               # if line contains }, set variable p=0

                      /}/{ 
                            p=0;
                         }

              # If line start with #, closing }, or empty line, skip

            /^#|}/ || !NF{ 
                            next 
                          }

               # if line contains pool[0-9]+ can be space or tab and then {, 
               # if variable h was set before
               # print newline,
               # set variable p =1, print 2nd field, go to next line

    /pool[0-9]+[ \t]+?{/{ 
                            if(h)print "";
                            p=1;
                            print $2;
                            next
                        }

               # as long as p is set,
               # print 3rd field from such record, 
               # h =1, to have newline char when awk finds news pool

                       p{
                            print $3;
                            h=1
                        }
              ' file

下面是测试结果:

输入:

$ cat file
server pool0 {
        0:server1:yes:profile_server1:192.168.1.1,192.168.1.2;
        1:server2:yes:profile_server2:192.168.1.3,192.168.1.4;
}

server pool1 {
        0:server3:yes:profile_server3:192.168.1.5,192.168.1.6;
        1:server4:yes:profile_server4:192.168.1.7,192.168.1.8;
}

#server pool2 {
#        0:server5:yes:profile_server5:192.168.1.9,192.168.1.10;
#        1:server6:yes:profile_server6:192.168.1.11,192.168.1.12;
#}

输出:

$ awk -F'[: ]+' '/\}/{p=0}/^#|\}/||!NF{next}/pool[0-9]+[ \t]+?\{/{if(h)print "";p=1;print $2;next}p{print $3;h=1}' file
pool0
server1
server2

pool1
server3
server4

遵循 awk 可能会对您有所帮助。

awk -F' +|:' '/^$/{flag="";next} /^server pool/{print $2;flag=1;next} flag && NF && !/}/{print $3}' Input_file

编辑:如果你的池块你可以有许多其他条目而不是服务器,那么我已经为它添加了一个额外的检查,尝试它然后让我知道。

awk -F' +|:' '/^$/{flag="";next} /^server pool/{print $2;flag=1;next} flag && NF && !/}/ && $3~/server/{print $3}'  Input_file

EDIT2:向OP 显示代码仅由 OP 提供预期输出。

awk -F' +|:' '/^$/{flag="";next} /^server pool/{print $2;flag=1;next} flag && NF && !/}/ && $3~/server/{print $3}' Input_file
pool0
server1
server2
pool1
server3
server4

GRPNAME="server pool0 {" GRPNAME=${GRPNAME%{*}; GRPNAME=${GRPNAME#*\\ }

where:
${GRPNAME%\{*} = delete everyting from end ("%") until 1st "{*"; the "\" is an escape character
${GRPNAME#*\ } = delete everything from beginning ("#")and stop after 1st space; ; the "\" is an escape character
egrep -o "^server pool[0-9]|^[^#][ ]+[0-9]:server[0-9]" file.txt | cut -d ':' -f2 | sed 's/\(server pool[1-9]\)/\n\1/g'

输出

server pool0
server1
server2

server pool1
server3
server4

笔记

我假设池总是从 0 开始,并且您不能拥有索引 > 9 的池。如果不是这种情况,您可以更改,例如[0-9][0-9]{1,2}到接受 -1 到 100 之间的数字。

这可能对你有用(GNU sed):

sed -nr '/^(server \S+).*/{s//\1/p;:a;n;s/^(([^:]*):){2}.*/\2/p;ta}' file

关注以server开头的行并从这些行中提取前两个单词。 从后续行中,提取第二个字段(使用:作为分隔符),直到发生匹配失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM