TCL 正则表达式在与变量名称一起使用时无法按预期工作



我正在使用tcl来执行一些模式匹配。以下是我正在对其执行匹配的字符串:

ps -ef | grep ipqosmgr
root     17255 17136  0 22:34 ttyS0    00:00:00 grep ipqosmgr
root     28986 17731  0 Jun05 ?        00:02:01 /isan/bin/ipqosmgr

通常我会想要第三行

root     28986 17731  0 Jun05 ?        00:02:01 /isan/bin/ipqosmgr

因为我想要与进程关联的进程 ID。

当我使用以下正则表达式时,它按预期工作:

% foreach line [split $output n] {
if { [ regexp -nocase {roots+([0-9]+)s+.*(/isan/bin/ipqosmgr)} $line - value ] } {
puts $line
}
}
root     28986 17731  0 Jun05 ?        00:02:01 /isan/bin/ipqosmgr
% puts $value
28986
% 

但是,我希望此代码为多个进程运行,因此将其放入一个具有$process的函数中,该函数将保存进程的值。当我对变量$process使用相同的正则表达式时,它会失败。

% puts $process
ipqosmgr
%
% foreach line [split $output n] {
if { [ regexp -nocase {roots+([0-9]+)s+.*(/isan/bin/$process)} $line - value ] } {
puts $line
}
}
% 
% puts $value
can't read "value": no such variable
% 

我不知道为什么它以这种方式行事,如果有人能告诉我这里出了什么问题以及如何纠正它,那就太好了。

您可以使用format准备正则表达式,如下所示:

foreach line [split $output n] {
set regex [format {roots+([0-9]+)s+.*(/isan/bin/%s)} $process]
if { [ regexp -nocase $regex $line - value ] } {
puts $line
}
}

使用表达式的方式的问题在于大括号会阻止变量替换,虽然您可以使用引号代替正则表达式,但您必须转义许多字符(例如方括号、反斜杠(并且为了避免转义这些字符,使用format可以更简单易用。

如果您打算使用字符串迭代,则应使用双引号字符串文字,并注意转义[]以防止将它们解释为命令以及转义每个以定义文字反斜杠(例如,此处s速记字符类(:

regexp -nocase "root\s+([0-9]+)\s+.*(/isan/bin/$process)" $line - value

在线观看 Tcl 演示。

这里

  • root- 子字符串root
  • \s+- 解析为s+- 1 个或多个空格字符
  • ([0-9]+)- 解析为([0-9]+)- 捕获组 1 - 1 个或多个数字
  • \s+- 1 个或多个空格
  • .*- 任何 0+ 字符
  • (/isan/bin/$process)- 解析为(/isan/bin/ipqosmgr)- 捕获与/isan/bin/ipqosmgr子字符串(或任何/isan/bin/+$process(匹配的组 1

subst命令中使用变量替换。此外,如果指定了任何-nobackslashes-nocommands-novariables,则不会执行相应的替换。例如,如果指定了-nocommands,则不执行命令替换:左括号和右括号被视为普通字符,没有特殊解释。

% set output "
root     17255 17136  0 22:34 ttyS0    00:00:00 grep ipqosmgr
root     28986 17731  0 Jun05 ?        00:02:01 /isan/bin/ipqosmgr
"

并设置变量

% set process "ipqosmgr"

你完全可以做到,

% foreach line [split $output n] {
if { [ regexp -nocase [subst -nocommands -nobackslashes {roots+([0-9]+)s+.*(/isan/bin/$process)}] $line - value ] } {
puts $line
}
}
root     28986 17731  0 Jun05 ?        00:02:01 /isan/bin/ipqosmgr

匹配是否按预期进行

% puts $value
28986

最新更新