我正在基于配置文件编写建筑环境,但无法解析它们。该环境包含Makefile(bmake),这些文件会尝试读取相应的设置CFLAGS
的配置。
配置文件保持简单,不需要特殊的=
签名:
ident Appname # E.g. core.S:15: .ident $ident$
cpu arch (amd64, x86) # -march=cpuarch -mtune=cpuarch
option debug # Enable debugging.
option sanitize # Sanitize undefined behaviour.
option asyncio # Asynchronous I/O.
option ccpipe # GCC/Clang -pipe option.
我无法找出使用grep
,sed
或awk
解析这些选项的正确正则表达式。因为我希望通过conditional statements
通过简单的bmake
(例如
DBG_ENABLED!= $read if option debug is set$ ? yes : no.
.if ${DBG_ENABLED} != ""} || ${DBG_ENABLED} == "yes" || ${DBG_ENABLED} != "no"
CFLAGS+= -O -g
.else
CFLAGS+= -O2
.endif
PIPE_ENABLED!= $read if option ccpipe is set$ ? yes : no.
.if ${PIPE_ENABLED} != "no"
CFLAGS+= -pipe
.endif
因此,如何通过外壳命令确定选项X
,例如option debug
,设置好了吗?我想到过要grepping文件或使用awk
...
答案 0 :(得分:3)
将配置文件读入关联数组:
$ declare -A opts="( $(awk -F'\t+' 'NF{print "["$1","$2"]=1"}' file) )"
$ for idx in "${!opts[@]}"; do echo "$idx=${opts[$idx]}"; done
cpu,arch (amd64, x86)=1
option,debug=1
option,asyncio=1
option,ccpipe=1
option,sanitize=1
ident,Appname=1
然后只需测试${opts["option,debug"]}
是否已填充。
或者,如果您只想获得这些选项:
$ declare -A opts="( $(awk -F'\t+' '$1=="option"{print "["$2"]=1"}' file) )"
$ for idx in "${!opts[@]}"; do echo "$idx=${opts[$idx]}"; done
ccpipe=1
sanitize=1
asyncio=1
debug=1
您喜欢的语法:
$ if (( ${opts[debug]} )); then echo "do debug stuff"; else echo "nope, dont do it"; fi
do debug stuff
$ if (( ${opts[fluff]} )); then echo "do debug stuff"; else echo "nope, dont do it"; fi
nope, dont do it
$ if [[ -n ${opts[debug]} ]]; then echo "do debug stuff"; else echo "nope, dont do it"; fi
do debug stuff
$ if [[ -n ${opts[fluff]} ]]; then echo "do debug stuff"; else echo "nope, dont do it"; fi
nope, dont do it
更新:由于您的文件显然不是按照您所说的那样用制表符分隔的,因此请删除注释,然后删除所有剩余的前导/后缀空格,并使用剩余的前一个空格链作为第一个字段与该行的其余部分(必须在第一个脚本中将arch (amd64, x86)
视为“字段”)
$ declare -A opts="( $(awk '{sub(/#.*/,""); gsub(/^[[:space:]]+|[[:space:]]+$/,"")} NF{k=$1; sub(/[^[:space:]]+[[:space:]]+/,""); print "["k","$0"]=1"}' file) )"
$ for idx in "${!opts[@]}"; do echo "$idx=${opts[$idx]}"; done
cpu,arch (amd64, x86)=1
option,debug=1
option,asyncio=1
option,ccpipe=1
option,sanitize=1
ident,Appname=1
$ declare -A opts="( $(awk '{sub(/#.*/,""); gsub(/^[[:space:]]+|[[:space:]]+$/,"")} $1=="option"{print "["$2"]=1"}' file) )"
$ for idx in "${!opts[@]}"; do echo "$idx=${opts[$idx]}"; done
ccpipe=1
sanitize=1
asyncio=1
debug=1
最终更新:所有考虑到的事情可能就是您真正想要的:
$ declare -A opts="( $(awk '
{
sub(/#.*/,"")
gsub(/^[[:space:]]+|[[:space:]]+$/,"")
}
NF && ($1 != "ident") {
f1 = $1
sub(/[^[:space:]]+[[:space:]]+/,"")
f2 = $0
if (f1 == "option") {
idx = f2
val = 1
} else {
idx = f1
val = f2
}
print "[" idx "]=\"" val "\""
}
' file ) )"
$ for idx in "${!opts[@]}"; do echo "$idx=${opts[$idx]}"; done
ccpipe=1
sanitize=1
asyncio=1
debug=1
cpu=arch (amd64, x86)