how to find the block name in which the string available ?
server.conf file
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;
#}
Notes:-
- "server_pool" is a static string
- "pool_name" can be any string without spaces
- "if a line has # in it ignore it
Requirement
- Need to find the "pool_name" by the provided server hostname as input i.e server{1,2,3,} and store it in a variable
for example
if need to find server1 belongs to which block/ stanza. in the given use case it belongs to odd, so store variable as POOLNAME=odd
grep -oP '^server\s\K[^ ]+|^[^#]\s+\d+:\K[^:]+' inputfile
pool0
server1
server2
pool1
server3
server4
Using 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
Better Readable:
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
Here is Test results:
Input:
$ 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;
#}
Output:
$ 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
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
Following awk may help you in same.
awk -F' +|:' '/^$/{flag="";next} /^server pool/{print $2;flag=1;next} flag && NF && !/}/{print $3}' Input_file
EDIT: If your pool block you could have many other entries other than servers then I have added an additional check for it, try it and let me know then.
awk -F' +|:' '/^$/{flag="";next} /^server pool/{print $2;flag=1;next} flag && NF && !/}/ && $3~/server/{print $3}' Input_file
EDIT2: Showing OP that code is providing the expected output by OP only.
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
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'
Output
server pool0
server1
server2
server pool1
server3
server4
Note
I suppossed that pool are always starting by 0 and that you can not have pool with an index > 9. If that's not the case you can change, for example [0-9]
to [0-9]{1,2}
to accept number between -1 and 100.
This might work for you (GNU sed):
sed -nr '/^(server \S+).*/{s//\1/p;:a;n;s/^(([^:]*):){2}.*/\2/p;ta}' file
Focus on lines that begin server
and extract the first two words from such lines. From subsequent lines, extract the second field (using :
as a separator) until a failure to match occurs.