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

时间:2017-10-04 06:53:39

标签: bash shell awk sed grep

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

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. “如果一行有#在其中忽略它
  4. 要求

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

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

6 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

使用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

答案 2 :(得分:0)

关注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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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开始,你不能拥有索引&gt;的池; 9.如果情况并非如此,您可以更改,例如[0-9][0-9]{1,2},以接受-1到100之间的数字。

答案 5 :(得分:0)

这可能适合你(GNU sed):

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

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