Правильный подход — просто вызвать awk один раз со списком IP-адресов, создать массив тегов/имен для значений(f[]
ниже )и просто получить доступ к значениям по их именам. Нет циклов оболочки (, которые были бы очень медленными ), и нет линий getlines (, см. http://awk.freeshell.org/AllAboutGetline, почему их обычно лучше избегать )требуется:
$ 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
-----
Я использую tag = val = $0
и т. д., чтобы отделить теги от их значений, а не полагаться на настройку FS="="
, поскольку =
может появляться в каталогах или именах файлов UNIX и, следовательно, может появляться в path
.
shopt -s extglob
изменяет синтаксис оболочки. Без этого оператора расширенный шаблон подстановки !($label|$label.json|active.json)
является недопустимым синтаксисом.
Проблема заключается в том, что до того, как оболочка выполнит команду shopt
, включающую параметр оболочки extglob
, весь оператор if
уже проанализирован и обнаружена синтаксическая ошибка.
Если строка, требующая изменения в разрешенном синтаксисе, не является частью составной команды (, которая представляет собой оператор if
), команда shopt
уже включила extglob
, что является почему это работает.
Чтобы решить эту проблему, включите extglob
перед оператором if
и отключите его после.
Это та же проблема, что и здесь.:Установка параметров bash в составной команде