-2

I am trying to find a line in haproxy configuration file:

global
        log 127.0.0.1   local0
        log 127.0.0.1   local1 notice
        #log loghost    local0 info
        maxconn 32768
        tune.maxaccept -1
        chroot /var/lib/haproxy
        daemon
        stats socket /var/run/haproxy.sock mode 600 level admin
        stats timeout 2m
        timeout http-request 5000

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 5
        option redispatch
        maxconn 16384
        timeout connect 7s
        timeout client  500s
        timeout server  500s
        timeout http-request 7000
        timeout client-fin      30s
        timeout tunnel  1h

What is the regex to match the line timeout http-request 5000 but only in global section. Also, we need to ensure to exclude #.

praving5
  • 87
  • 1
  • 9

4 Answers4

1

You can use the pattern

^global\b(?:(?:(?:#|[ \t]+)[^\n]*|)\n)*?\s+(timeout\s+http-request\s+\d+)

with multiline modifier m. This should support commented lines (with #) and doesn't rely on the defaults section being after the globals section like all the other answers seem to do.

The text timeout http-request 5000 will be in capture group 1.

Regex101 demo.

Explanation:

^global\b      find the "global" section, this must not be indented
(?:            then consume any number of lines that are...
   (?:
      (?:#     ...commented...
      |[ \t]+) ...or indented...
      [^\n]*   
      |        ...or empty
    )\n
)*?
\s+(timeout\s+http-request\s+\d+)   finally capture the line we're looking for
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • This works. I am not sure why others have marked this question as a "need to learn regex" question. I know regex pretty well but yeah not a pro to write such complex regex. Anyways, thanks a lot Rawing for helping me out, I will try using regex101 from now on. Thanks a lot again. – praving5 May 01 '16 at 22:23
  • Hi @Rawing, Stuck again. `case "$1" in start) echo -n "Starting haproxy " ## Start daemon with startproc(8). If this fails ## the return value is set appropriately by startproc. haproxy_check /sbin/startproc $HAPROXY_BIN -D -f $HAPROXY_CONF -p $HAPROXY_PID # Remember status and be verbose rc_status -v ;; ` - in this i want to match haproxy_check. I tried various things including `^\s*start\)(?:(?:(?:#|[ \t]+)[^\n]*|)\n)*?^\s*haproxy_check`. This seems to timeout if haproxy_check is commented out. Any help? – praving5 May 31 '16 at 04:44
  • @praving5 You need to give some more details about what you're trying to do. If all you say is "I want to match haproxy_check", then, well, the regex `haproxy_check` should do. Probably best to post a new question. – Aran-Fey May 31 '16 at 15:19
0

Have a look at this regex: https://regex101.com/r/sI5qY6/1

/global.*(timeout\s+http-request\s+\d+).*?defaults/s

It gives following match:

MATCH 1
1.  [304-329]   `timeout http-request 5000`
AKS
  • 18,983
  • 3
  • 43
  • 54
0

This one will probably do it very fast only in 66 steps in case timeout http-request 5000 is at the very end of global

timeout\shttp-request\s+\d+(?=\s*defaults)

Regular expression visualization

Debuggex Demo

https://regex101.com/r/yW9xZ6/2

if timeout http-request 5000 can be placed anywhere in global group then

/timeout\shttp-request\s+\d+(?=[\s\S]+defaults)/m

https://regex101.com/r/yW9xZ6/3

Redu
  • 25,060
  • 6
  • 56
  • 76
0

awk is handy to search winthin a block.

Give this a try:

awk -F "#" '/^global/,/^defaults/ {if ($1 ~ /timeout *http-request/) {print $1}}' haproxy.conf

-F "#" define # as field separator, so $1 is the string before # in current line.

'/^global/,/^defaults/ { for all lines within the block defined between global and defaults, do the actions between {}.

if ($1 ~ /timeout *http-request/ it is true if the string before # (if any), contains the property timeout *http-request.

Jay jargot
  • 2,745
  • 1
  • 11
  • 14