How do I search a file for a pattern, then extract part of the pattern or supply a default if the pattern does not exist? Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of How do I search a file for a pattern, then extract part of the pattern or supply a default if the pattern does not exist? without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I’m trying to write a script that searches through a pre-made list of running processes across a series of machines. I’m specifically looking for rsyslogd running on those devices, and attempting to find what configuration file they’re using (if not using the default /etc/rsyslog.conf).

Right now I’m successfully searching through the machines with this for loop:

for root_file in $TARGET_DIR/RESULTS*/ps_results; do
    grep rsyslogd $root_file | awk '{s = ""; for (i = 15; i <= NF; i++) s = s $i " "; print s}'
done

And it’ll return a list like

# get_configs $TARGET_DIR/
/usr/sbin/rsyslogd -n
/sbin/rsyslogd -i /var/run/syslogd.pid -c 5
/usr/sbin/rsyslogd -n -f /usr/syslog.conf
...

But what I want is a list that shows the IP address of the machine that is being checked (which is in the * of the RESULTS* of the script as-is) followed by just the path to the configuration file, like so:

# get_configs $TARGET_DIR/
172.16.10.1     /etc/syslog.conf
172.16.10.2     /etc/syslog.conf
172.17.5.245    /usr/syslog.conf
... 

I’ll be taking this list and parsing through the files and finding any additional configuration files that they might link to with the $IncludeConfig directive, but I’ve got to get through cleaning up my list of files first.

The mental block I’m hitting is testing for the -f option following rsyslogd. Since rsyslogd doesn’t require -f and it runs with the default /etc/rsyslog.conf, how do I handle testing for the option and extracting the path following it or supplying a default?

I considered using sed or cut to isolate ‘ -f /path/to/file’ and return /etc/rsyslog.conf on an empty result, but I’m not managing to accomplish that.

Answer

Supposing we have the following input files

$ grep . */ps_results
RESULTS-172.16.10.1/ps_results:/usr/sbin/rsyslogd -n
RESULTS-172.16.10.2/ps_results:/sbin/rsyslogd -i /var/run/syslogd.pid -c 5
RESULTS-172.17.5.245/ps_results:/usr/sbin/rsyslogd -n -f /usr/syslog.conf
$

Then how about

$ awk '/rsyslogd/{gsub("^.*RESULTS-","",FILENAME);gsub("/ps_results","",FILENAME);b="/etc/rsyslog.conf";for(a=0;a++<NF;){if($a=="-f"){b=$(a+1)}};printf "%-15s%sn",FILENAME,b}' RESULTS*/ps_results
172.16.10.1     /etc/rsyslog.conf
172.16.10.2     /etc/rsyslog.conf
172.17.5.245    /usr/syslog.conf
$

Same code, annotated+formatted:

awk '/rsyslogd/ {
   # strip everything up to (and including) RESULTS- from the filename
   gsub("^.*RESULTS-","",FILENAME)
   # strip the /ps_results from the filename
   gsub("/ps_results","",FILENAME)
   # set the default rsyslog conf file
   b="/etc/rsyslog.conf"
   # look for a -f parameter: if found, grab conf file
   for(a=0;a++<NF;){
     if($a=="-f") {
       b=$(a+1)
     }
   }
   # print the ip addr and conf file
   printf "%-15s%sn",FILENAME,b
}' RESULTS*/ps_results
We are here to answer your question about How do I search a file for a pattern, then extract part of the pattern or supply a default if the pattern does not exist? - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji