1

The AWK statement uses the variable $ip to search each line, but I need to print the variable $ip NOT FOUND in the ELSE statement for ips that are not found in the config.

Can't get it to work with IF ELSE, to reuse the $ip variable in the ELSE statement, so it would print 999.999.999.999 NOT IN CONFIG!

also, if possible to not use redundant getline getline getline's, like maybe a way to just skip 3 lines?

 declare -a iplist=(
 "192.168.0.10" 
 "192.168.0.20" 
 "192.168.0.30" 
 "999.999.999.999"
)

for ip in "${iplist[@]}"; do

awk "/$ip/" '{if {print $0; getline; getline; getline; print $0; print "-----"} else {print "/$ip/" "NOT FOUND"}' /home/user/D1/config

### BELOW WORKS - But, need the IF ELSE Statement ###
awk "/$ip/"'{print $0; getline; getline; getline; print $0; print "-----"}' /home/user/D1/config
done

config file contents:

ip=192.168.0.10
mask=255.255.255.0
allow=on
text=off
path=/home/user/D1/test/server1
-----
ip=192.168.0.20
mask=255.255.255.0
allow=on
text=off
path=/home/user/D1/test/server1
-----
ip=192.168.0.30
mask=255.255.255.0
allow=on
text=off
path=/home/user/D1/test/server1
-----

Desired output:

ip=192.168.0.10
path=/home/user/D1/test/server1
-----
ip=192.168.0.20
path=/home/user/D1/test/server1
-----
ip=192.168.0.30
path=/home/user/D1/test/server1
-----
ip=192.168.0.30
path=/home/user/D1/different-path-than-line-above/server1
-----
ip=999.999.999.999 NOT IN CONFIG
-----
odessa
  • 11

1 Answers1

1

The right approach is to just call awk once with the list of IPs, create an array of tags/names to values (f[] below) and just access the values by their names. No shell loop (which would be extremely slow), and no getlines (see http://awk.freeshell.org/AllAboutGetline for why those are usually best avoided) required:

$ cat tst.sh
#!/bin/env bash

declare -a iplist=(
    '192.168.0.10'
    '192.168.0.20'
    '192.168.0.30'
    '999.999.999.999'
)

awk -v iplist="${iplist[*]}" '
    BEGIN {
        split(iplist,tmp)
        for (idx in tmp) {
            ip = tmp[idx]
            cnt[ip] = 0
        }
        OFS = "="
        sep = "-----"
    }
    {
        tag = val = $0
        sub(/=.*/,"",tag)
        sub(/^[^=]+=/,"",val)
        f[tag] = val
    }
    $0 == sep {
        ip = f["ip"]
        if ( ip in cnt ) {
            cnt[ip]++
            print "ip", ip
            print "path", f["path"]
            print sep
        }
        delete f
    }
    END {
        for (ip in cnt) {
            if ( cnt[ip] == 0 ) {
                print "ip", ip " NOT IN CONFIG"
                print sep
            }
        }
    }
' config

.

$ ./tst.sh
ip=192.168.0.10
path=/home/user/D1/test/server1
-----
ip=192.168.0.20
path=/home/user/D1/test/server1
-----
ip=192.168.0.30
path=/home/user/D1/test/server1
-----
ip=999.999.999.999 NOT IN CONFIG
-----

I use tag = val = $0, etc. to separate the tags from their values rather than relying on setting FS="=" since = can appear in UNIX directory or file names and so could appear in a path.

Ed Morton
  • 31,617
  • it works, but sometimes there are duplicate IP addresses in the configuration file, and it needs to find those as well, as the duplicates have native paths. well that be a big change? – odessa Sep 08 '19 at 16:32
  • It's no change at all - best I can tell the script will behave as desired as-is. Did you try it? If there's a case it doesn't work for then include that case in the sample input/output in your question. – Ed Morton Sep 08 '19 at 16:35
  • yes, I did try it. also the sep ----- dashes are added to the config by the system daemon, so it would be best to not print them, but let the statement print whats there. like maybe a print the next line syntax. – odessa Sep 08 '19 at 16:55
  • 1
    wrt it would be best to not print them - if you don't want them printed then don't include them in your expected output. It sounds like you have a few important things not covered in your question so update your question to contain all relevant information and an accurate example. – Ed Morton Sep 08 '19 at 17:15
  • those are pretty much all the important details to add. originally I just wanted to use a one liner with the IF ELSE to keep it simple for other users. Is that possible? or is the IF ELSE statement not capable of having the ELSE use the $ip variable match – odessa Sep 08 '19 at 19:49
  • Yes, you can use an else, I'm personally not going to help you write code that requires a shell loop and multiple passes of the input file to work but maybe someone else will. Good luck! – Ed Morton Sep 09 '19 at 17:49