Search code examples
bashawksedgrepmod-security2

Cut Mod_Security ID with sed/awk


I would like to cut the numbers between the quotas of a Mod_sec ID: [id "31231"]. Generally it is not difficult at all but when I am trying to extract all IDs from multiple reports such as:

[Wed Oct 19 15:31:33.460342 2016] [:error] [pid 16526] [client 67.22.202.121] ModSecurity: Access denied with code 400 (phase 2). Operator EQ matched 0 at REQUEST_HEADERS. [file "/usr/local/apache/conf/includes/mod_security2.conf"] [line "4968"] [id "000784"] [hostname "example.org"] [uri "/"] [unique_id "WAfYJU1ol@MAAECO@HQAAAAI"]

[Wed Mar 19 15:31:33.460342 2016] [:error] [pid 16526] [client 67.22.202.121] ModSecurity: Access denied with code 400 (phase 2). Operator EQ matched 0 at REQUEST_HEADERS. [file "/usr/local/apache/conf/includes/mod_security2.conf"] [line "4968"] [id "9"] [hostname "example.org"] [uri "/"] [unique_id "WAfYJU1ol@MAAECO@HQAAAAI"]

[Wed Mar 19 15:31:33.460342 2016] [:error] [pid 16526] [client 67.22.202.121] ModSecurity: Access denied with code 400 (phase 2). Operator EQ matched 0 at REQUEST_HEADERS. [file "/usr/local/apache/conf/includes/mod_security2.conf"] [line "4968"] [id "00263"] [hostname "example.org"] [uri "/"] [unique_id "WAfYJU1ol@MAAECO@HQAAAAI"]

I have attempted several commands such as:

cat asd | awk '/\[id\ "/,/"]/{print}'
cat asd | sed -n '/[id "/,/"]/p'

and many others but they do not print the required IDs but rather include additional output since the pattern is being matched several times. Generally I am able to do something like:

cat asd | egrep -o "\"[0-9][0-9][0-9][0-9][0-9][0-9]\"" and then cut the output again but this does not work in cases where the ID does not contain 6 numbers.

I am not familiar with all options of awk,sed and egrep and do not seem to find a solution.

What I would like to be printed from above history is:

000784

9

00263

Could someone please help. Thank you in advance.


Solution

  • With grep if pcre option is available:

    $ grep -oP 'id "\K\d+' asd 
    000784
    9
    00263
    
    • id "\K positive lookbehind to match id ", not part of output
    • \d+ the digits following id "


    With sed

    $ sed -nE 's/.*id "([0-9]+).*/\1/p' asd 
    000784
    9
    00263
    
    • .*id " match up to id "
    • ([0-9]+) capture group to save digits needed
    • .* rest of line
    • \1 entire line replaced only with required string