Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible regular expression to match a string and extract the line

Tags:

regex

ansible

I'm trying to find a string after 1 white space in a line, if it exists then extract the complete line and store in a different variable. I'm using ansible and regular expression. If the string exists in any other place then it should not be matched.

I tried to use regex_match and select but got error.

  vars:
    input : "{{ lookup('template', '{{ file }}') }}"
    target: "{{ input | regex_search('^(?=.*\b INPUT\b)(?:\S+){1}(\S*.*)')}}"

Error always appear at same place "(?:\S+)".

ERROR! Syntax Error while loading YAML.
  found unknown escape character 'S'

The offending line appears to be:

    input : "{{ lookup('template', '{{ file }}') }}"
    target: "{{ input | regex_search('^(?=.*\b INPUT\b)(?:\S+){1}(\S*.*)')}}"

^ here
    input : "{{ lookup('template', '{{ file }}') }}"
    target: "{{ input | select('match', '^(?=.*\b INPUT\b)(?:\S+){1}(\S*.*)' | list | first}}"

^ here

I also tried to include escape character for / but got error as well.

ERROR! Syntax Error while loading YAML.
  found unknown escape character 'S'

The offending line appears to be:

   input : "{{ lookup('template', '{{ file }}') }}"
    target: "{{ input | regex_search('^(?=.*/\b INPUT/\b)(?:/\S){1}(/\S*.*)')}}"
                                                                                ^ here

My variable file

-P INPUT ACCEPT
-A INPUT -s 1.1.1.1/32 -j ACCEPT
-A INPUT -s 2.2.2.2/32 -j ACCEPT
-A INPUT -s 3.3.3.3/32 -j ACCEPT
-A INPUT -j RH-Firewall
-N RH-Firewall
-A RH-Firewall -j INPUT
-A RH-Firewall -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A RH-Firewall -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A RH-Firewall-1 -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A RH-Firewall -p icmp -m icmp --icmp-type 11 -j ACCEPT

target_rule_set should contains first 5 lines only. Same way if I match for RH-Firewall then it should contain lines 6-11.

like image 845
Knightfox Avatar asked Jan 22 '26 22:01

Knightfox


1 Answers

You may use regex_findall with multiline=True:

(?m)^\S+\s+INPUT\b.*

See the regex demo. Details:

  • ^ - start a line since (?m) is used
  • \S+ - 1+ non-whitespace chars
  • \s+ - 1+ whitespaces
  • INPUT\b - INPUT as a whole word
  • .* - the rest of the line.

In the code:

target: "{{ input | regex_findall('^\\S+\\s+INPUT\\b.*', multiline=True)}}"
like image 85
Wiktor Stribiżew Avatar answered Jan 25 '26 17:01

Wiktor Stribiżew