问题描述
我正在尝试使用bash regex匹配从多行字符串中解析出一行。为什么以下方法不起作用?
if [[ $qout =~ ${q}[^\n]* ]] ; then
它与字母n
匹配。我尝试使用\\n
甚至\\\n
,但没有任何效果。
$qout
包含:
unrouted 0 0 running
dead-letter 0 0 running
$q
包含unrouted
。
${BASH_REMATCH[0]
的计算结果为:
unrouted 0 0 ru
我在做什么错了?
解决方法
假设:
- 从多行变量(
qout
)中提取包含模式(q
)的行 - 从模式(
q
)提取到行尾(将在${BASH_REMATCH[0]}
中捕获)
对多行变量进行了一些修改:
$ echo ${qout)
this is unrouted 0 0 running
dead-letter 0 0 running
注意:我在第一行添加了“ this is”前缀,以便我们可以验证解析的开始位置。
一个主意-从此答案中借用(shell regex to end of line):
$ sfx=$'[^\n]*' # match up to first newline (`\n`) character;
# must use single quotes;
# double quotes will cause the `\n` to be evaluated as the character `n`
$ [[ $qout =~ ${q}${sfx} ]] && echo 'match'
match
$ echo "${BASH_REMATCH[0]}"
unrouted 0 0 running
FWIW,将测试/ echo
包装在set -/+ xv
中显示:
$ [[ $qout =~ ${q}${sfx} ]] && echo 'match'
+ [[ this is unrouted 0 0 running
dead-letter 0 0 running =~ unrouted[^
]* ]]
+ echo match
match
在组合中添加@David C. Rankin的注释(将\n
直接放在正则表达式中):
$ [[ $qout =~ ${q}[^$'\n']* ]] && echo 'match'
match
$ echo "${BASH_REMATCH[0]}"
unrouted 0 0 running
注意:如果David想发布自己的答案,我可以删除它。
, [\n]
与换行符不匹配-它与文字反斜杠或n
匹配。如果您运行nl=$'\n'
然后使用$nl
作为您的正则表达式,那么事情将按预期进行。
#!/usr/bin/env bash
qout='unrouted 0 0 running
dead-letter 0 0 running'
q=unrouted
nl=$'\n'
if [[ $qout =~ ${q}[^$nl]*[$nl] ]]; then
declare -p BASH_REMATCH
else
echo "No match found" >&2
fi
...作为输出发出:
declare -ar BASH_REMATCH=([0]=$'unrouted 0 0 running\n')