Home > Net >  Regex to extract a config section containing certain key pair value from a config file
Regex to extract a config section containing certain key pair value from a config file

Time:02-04

The goal is as the title says. It felt simple at first, but I just couldn't do it by myself.

Here's an example of the file:

config wifi-device 'radio0'
option type 'mac80211'
option band '2g'

config wifi-iface 'default_radio0'
option device 'radio0'
option mode 'ap'
option ssid '2.4G'
option network 'WLAN'

config wifi-device 'radio1'
option type 'mac80211'
option band '5g'

config wifi-iface 'default_radio1'
option device 'radio1'
option mode 'ap'
option ssid '5G'

Basically all I wanted to do was to get the corresponding device by ssid, and I'm trying to do that with the intermediate step of extracting a config section first. The example is a simplified version of the wireless config on openwrt, but I'm not limited to use the native tool set, as I'm managing these AP remotely.

Consider the ssid 5G, I get the whole file back with grep -P (?s)(?=config).*?5G.*?(?=\n\n) when I just want

config wifi-iface 'default_radio1'
option device 'radio1'
option mode 'ap'
option ssid '5G'

I'm already trying something else like splitting the file first but it just doesn't feel necessary and I think I'm missing something. Appreciate any help!

CodePudding user response:

Use this Perl one-liner to split the config file into paragraphs ($/ = "";), and print the one with ssid '5G':

perl -ne 'BEGIN { $/ = ""; } chomp; if ( m{option ssid .5G.} ) { print "$_\n"; }' test1.cfg
config wifi-iface 'default_radio1'
option device 'radio1'
option mode 'ap'
option ssid '5G'

SEE ALSO:
perldoc perlrun: how to execute the Perl interpreter: command line switches

CodePudding user response:

Using gnu-grep you can read the whole file with -z and use -o to print only the matches.

Start the match with config and match all following lines starting with option and then match the last line that contains ssid '5G'

grep -oPz '(?:^|\n\n)\Kconfig\h.*(?:\noption\h.*)*\noption\hssid\h\x275G\x27.*(?=\n\n|$)' file

The pattern matches:

  • (?:^|\n\n) Assert the start of the string or match 2 newlines
  • \K Forget what is matched so far
  • config\h.* Match config and the rest of the line
  • (?:\noption\h.*)* Repeat matching all lines that start with option
  • \noption\hssid\h\x275G\x27 Match a newline, then option ssid '5G'
  • .* Match the rest of the line
  • (?=\n\n|$) Positive lookahead, assert either 2 newlines or the end of the string

Output

config wifi-iface 'default_radio1'
option device 'radio1'
option mode 'ap'
option ssid '5G'
  • Related