我有些文件看起来像这样
LiveData
我想解析每个文件,并对定义 service {和} 之间的每个节执行以下操作:
如果我在 service_description 行上找到了一项键盘输入(在另一个用作参考的文件中列出),我想检查gen-infra是否存在于 use 行上,否则我需要在gen-svc之前添加它。
如果在 service_description 行上,我找不到列出的关键字之一,并且如果 gen-appli 行上不存在< em>使用,添加它!
示例:
如果找到 check2 ,则应添加gen-infra(如果不存在),因此上面的节应为
define host{
use gen-host
host_name AA1234
......
}
define service{
use gen-perf,gen-infra,gen-svc
host_name AA1234
service_description check1
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
}
define service{
use gen-svc
host_name AA1234
service_description check2
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
}
define service{
use gen-appli,gen-svc
host_name AA1234
service_description check3
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
}
define service{
use gen-perf,gen-svc
host_name AA1234
service_description check4
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
}
define service{
use gen-appli,gen-svc
host_name AA1234
service_description check5
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
}
check4 不在参考列表中,所以如果不存在,我应该添加gen-appli,因此上面的节应为
define service{
use gen-infra,gen-svc
host_name AA1234
service_description check2
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
}
使用sed,如果找到列出的关键字之一,我设法添加了 gen-infra ;如果找不到任何关键字,则添加了 gen-appli 。>
define service{
use gen-perf,gen-appli,gen-svc
host_name AA1234
service_description check4
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
}
$ {INFRA_LST}包含基于参考文件的关键字列表。 $ {INFRA_LST}如下所示(当然还有更多的关键字):
sed -i "/define service/,/}/{H;d;};x;/service_description\s*${INFRA_LST}/! s/use\s*\([[:graph:]]*\)\(gen-svc\)\(.*\)/use\t\t\t\t\1gen-appli,\2\3/g" FILE_TO_PARSE.txt
sed -i "/define service/,/}/{H;d;};x;/service_description\s*${INFRA_LST}/ s/use\s*\([[:graph:]]*\)\(gen-svc\)\(.*\)/use\t\t\t\t\1gen-infra,\2\3/g" FILE_TO_PARSE.txt
在现实生活中,我可以拥有除gen-svc之外的其他东西,因此可以解释该组,因为其中存在OR条件。
但是,如果尚不存在 gen-infra 或 gen-appli ,如何仅添加第二条条件呢?> >
答案 0 :(得分:0)
我在bash中的解决方案。
sed
是解析行的简单好工具,对于多行解析,使用适当的语言更简单。
脚本规则为:
service_description
标签等于字符串check2
,则程序应在gen-infra
标签中添加名称use
。service_description
标签与字符串check4
不相等,则程序应在gen-appli
标签中添加名称use
。use
标记中名称的顺序无关紧要,并用,
逗号分隔。use
中至少已经有一个名称。
#!/bin/bash
set -euo pipefail
assert() { if ! eval "$1"; then echo "Assertion '$1' failed!" >&2; exit 1; fi; }
add_name_to_use() {
local service name
service=$1
name=$2
sed '/^[[:space:]]*use[[:space:]]*/{/'"$name"'/b;s/$/,'"$name"'/}' <<<"$service"
}
cmp_service_description() {
local service value
service=$1
shift
greparg='^[[:space:]]*service_description[[:space:]]*\('
for i; do
greparg+="$i\\|"
done
greparg=$(sed 's/\\|$//'<<<"$greparg")
greparg+='\)$'
grep -q "$greparg" <<<"$service"
}
handle_one_service() {
local service
service=$1
# If I find check2,
if cmp_service_description "$service" "check2" "keyword2" "and so on..."; then
# I should add gen-infra if not present
service=$(add_name_to_use "$service" "gen-infra")
fi
# if check4 is not in the reference list
if ! cmp_service_description "$service" "check4"; then
# I should add gen-appli
service=$(add_name_to_use "$service" "gen-appli")
fi
echo "$service"
}
inservice=false
str=""
while IFS= read -r line; do
str+="$line"$'\n'
case "$line" in
"define service{")
inservice=true
;;
*"}"*)
if "$inservice"; then
inservice=false
handle_one_service "$str"
else
echo "$str"
fi
str=""
;;
esac
done
我已经编写了函数cmp_service_description
,因此您可以检查多个(列表)值。
将输出与输入列进行比较。在原始文件的左侧,在脚本输出的右侧:
$ paste -d'#' 1 <(./parse.sh <1) | column -t -s'#' -o' | '
define host{ | define host{
use gen-host | use gen-host
host_name AA1234 | host_name AA1234
...... | ......
} | }
|
define service{ |
use gen-perf,gen-infra,gen-svc | define service{
host_name AA1234 | use gen-perf,gen-infra,gen-svc,gen-appli
service_description check1 | host_name AA1234
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | service_description check1
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
} | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
| }
define service{ |
use gen-svc | define service{
host_name AA1234 | use gen-svc,gen-infra,gen-appli
service_description check2 | host_name AA1234
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | service_description check2
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
} | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
| }
define service{ |
use gen-appli,gen-svc | define service{
host_name AA1234 | use gen-appli,gen-svc
service_description check3 | host_name AA1234
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | service_description check3
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
} | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
| }
define service{ |
use gen-perf,gen-svc | define service{
host_name AA1234 | use gen-perf,gen-svc
service_description check4 | host_name AA1234
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | service_description check4
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
} | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
| }
define service{ |
use gen-appli,gen-svc |
host_name AA1234 | define service{
service_description check5 | use gen-appli,gen-svc
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | host_name AA1234
xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy | service_description check5
} | xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
| xxxxxxxxxxxxxxx yyyyyyyyyyyyyyy
| }