在使用包含正则表达式的变量时,我遇到了sed和back-referencig的问题。 它是用bash编写的解析器。在更早的时候,我想使用sed将每一行清理成所需的数据:缩进,键和值(冒号分隔)。数据类似于yaml但使用等于。 数据的基本示例:
overview = peparing 2016-10-22
license= sorted 2015-11-01
我遇到问题的函数在while循环中执行逻辑:
function prepare_parsing () {
local file=$1
# regex components:
local s='[[:space:]]*' \
w='[a-zA-Z0-9_]*' \
fs=':'
# regexes(NoQuotes, SingleQuotes, DoubleQuotes):
local searchNQ='^('$s')('$w')'$s'='$s'(.*)'$s'$' \
searchSQ='^('$s')('$w')'$s'='$s\''(.*)'\'$s'\$' \
searchDQ='^('$s')('$w')'$s'='$s'"(.*)"'$s'\$' \
replace="\1$fs\2$fs\3"
while IFS="$fs" read -r indentation key value; do
...
SOME CUSTOM LOGIC
...
done < <(sed -n "s/${searchNQ}/${replace}/p" $file)
}
尝试调用该函数时,我收到已知的无效引用错误到\ 3:invalid reference \3 on s' command's RHS
为了调试这个,在vars定义之后,我使用printf和%q选项打印了它们的值。
printf "%q\n" $searchNQ $searchSQ $searchDQ $replace
获取这些值:
\^\(\[\[:space:\]\]\*\)\(\[a-zA-Z0-9_\]\*\)\[\[:space:\]\]\*=\[\[:space:\]\]\*\(.\*\)\[\[:space:\]\]\*\$
\^\(\[\[:space:\]\]\*\)\(\[a-zA-Z0-9_\]\*\)\[\[:space:\]\]\*=\[\[:space:\]\]\*\'\(.\*\)\'\[\[:space:\]\]\*\\\$
\^\(\[\[:space:\]\]\*\)\(\[a-zA-Z0-9_\]\*\)\[\[:space:\]\]\*=\[\[:space:\]\]\*\"\(.\*\)\"\[\[:space:\]\]\*\\\$
$'\\1\034\\2\034\\3'
也许这就是问题,shell(bash)扩展变量时的过多转义序列(例如,它似乎是转义*,[],...)。
如果我将-r选项传递给sed,它可以正常工作,但我必须避免这种情况,因为执行脚本的系统不会有这个sed实现:我必须使用基本的sed。
您是否知道如何将正则表达式存储到变量中并使它们可用于RHS上的反向引用?
它适用于以下两种情况:
使用普通正则表达式字符串时:
sed -n "s/^\([[:space:]]*\)\([a-zA-Z0-9_]*\)[[:space:]]*=[[:space:]]*\(.*\)[[:space:]]*\$/\1:\2:\3/p" $file
当我只使用vars,w和fs:
sed -n "s/^\($s\)\($w\)$s=$s\(.*\)$s\$/\1$fs\2$fs\3/p" $file
非常感谢您的帮助!
答案 0 :(得分:0)
perl可以用来代替sed,比如
fw.close();