Tcl 使用grep获取行号

Tcl 使用grep获取行号,tcl,Tcl,我想使用grep命令获取行号,但当搜索模式不是单个单词时,我会收到错误消息: couldn't read file "Pattern": no such file or directory 如何正确使用grep?代码如下: set status [catch {eval exec grep -n '$textToGrep' $fileName} lineNumber] if { $status != 0 } { #error } else { puts "lineNumber

我想使用
grep
命令获取行号,但当搜索模式不是单个单词时,我会收到错误消息:

couldn't read file "Pattern": no such file or directory
如何正确使用grep?代码如下:

set status [catch {eval exec grep -n '$textToGrep' $fileName} lineNumber]
if { $status != 0 }  {
    #error
} else {
    puts "lineNumber = $lineNumber"
} 
此外,如果搜索模式根本不匹配,则返回值为:
“子进程异常退出”

下面是一个简单的测试用例:

 set textToGrep  "<BBB name=\"BBBRM\""

set textToGrep”好吧,我还发现你的代码和一个单词模式有问题

首先,我认为您不需要
eval
命令,因为
catch
本身对其第一个参数进行求值

然后,问题是将
$textToGrep
变量放在
exec
中的单引号
'
中,这对Tcl没有任何意义

因此,如果
textToGrep
的内容是
foo
,则要求
grep
搜索字符串
'foo'
。如果文件中未找到该字符串,包括单引号,则会出现错误

试着用英语重写你的第一行

set status [catch {exec grep -n $textToGrep $fileName} lineNumber]

看看它是否有效。另外,请阅读
exec
手册页,它很好地解释了这些问题。

好吧,我还发现您的代码和单个单词模式存在问题

set textToGrep {\<BBB name="BBBRM"}
catch {exec grep -n $textToGrep $fileName} status 
if {![regexp "child process" $status]} {
puts $status
} else {
puts "no word found" 
} 
首先,我认为您不需要
eval
命令,因为
catch
本身对其第一个参数进行求值

然后,问题是将
$textToGrep
变量放在
exec
中的单引号
'
中,这对Tcl没有任何意义

因此,如果
textToGrep
的内容是
foo
,则要求
grep
搜索字符串
'foo'
。如果文件中未找到该字符串,包括单引号,则会出现错误

试着用英语重写你的第一行

set status [catch {exec grep -n $textToGrep $fileName} lineNumber]

另外,请阅读
exec
手册页,其中很好地解释了这些问题。

set textToGrep{\
set textToGrep{\这里有两个问题:

set textToGrep {\<BBB name="BBBRM"}
catch {exec grep -n $textToGrep $fileName} status 
if {![regexp "child process" $status]} {
puts $status
} else {
puts "no word found" 
} 
  • 模式匹配不起作用
  • grep退出,子进程出现错误
    
    未找到模式时异常退出
第一个问题是,您没有将
textToGrep
括在
双引号中(而不是单引号)。因此,您的代码应该是:

[catch {exec grep -n "$textToGrep" $fileName} lineNumber]
第二个问题是由于
grep
命令的退出状态。
grep
在找不到模式时出错退出。以下是试用shell:

# cat file
pattern
pattern with multiple spaces
# grep pattern file
pattern
pattern with multiple spaces
# echo $?
0
# grep nopattern file
# echo $?
1
编辑:

在您的情况下,您有一些特殊字符,例如
(在shell上有特殊含义)

set textToGrep“”textToGrep

这里有两个问题:

  • 模式匹配不起作用
  • grep退出,子进程出现错误
    
    未找到模式时异常退出
第一个问题是,您没有将
textToGrep
括在
双引号中(而不是单引号)。因此,您的代码应该是:

[catch {exec grep -n "$textToGrep" $fileName} lineNumber]
第二个问题是由于
grep
命令的退出状态。
grep
在找不到模式时出错退出。以下是试用shell:

# cat file
pattern
pattern with multiple spaces
# grep pattern file
pattern
pattern with multiple spaces
# echo $?
0
# grep nopattern file
# echo $?
1
编辑:

在您的情况下,您有一些特殊字符,例如
(在shell上有特殊含义)

set textToGrep“”textToGrep

如果您的系统安装了tcllib,您可以使用
fileutil
软件包中的
fileutil::grep
命令:

package require fileutil

set fileName data.xml
set textToGrep {<BBB +name="BBBRM"}; # Update: Add + for multi-space match
set grepResult [::fileutil::grep $textToGrep $fileName]
foreach result $grepResult {
    # Example result:
    # data.xml:4:  <BBB name="BBBRM" />
    set lineNumber [lindex [split $result ":"] 1]
    puts $lineNumber

    # Update: Get the line, squeeze the spaces before name=
    set line [lindex [split $result ":"] 2]
    regsub { +name=} $line " name=" line
    puts $line
}   
包需要fileutil
设置文件名data.xml

设置textToGrep{如果系统安装了tcllib,则可以使用
fileutil
软件包中的
fileutil::grep
命令:

package require fileutil

set fileName data.xml
set textToGrep {<BBB +name="BBBRM"}; # Update: Add + for multi-space match
set grepResult [::fileutil::grep $textToGrep $fileName]
foreach result $grepResult {
    # Example result:
    # data.xml:4:  <BBB name="BBBRM" />
    set lineNumber [lindex [split $result ":"] 1]
    puts $lineNumber

    # Update: Get the line, squeeze the spaces before name=
    set line [lindex [split $result ":"] 2]
    regsub { +name=} $line " name=" line
    puts $line
}   
包需要fileutil
设置文件名data.xml


设置textToGrep{您确定文件包含您正在搜索的内容吗?查看
exec
手册页,您有一个示例,可以使用
try…except
catch
进行检查。当文件中找不到模式时,
grep
将以非零结果退出,并且您的脚本将显示错误。当然,是我正在搜索文件中的。我得到的错误如下:无法读取文件”模式应该是搜索":没有这样的文件或目录这是我的建议;无论问题是什么,它都回答了问题本身。你确定该文件包含你正在搜索的内容吗?查看
exec
手册页,你有一个示例,当在文件,
grep
以非零结果退出,您的脚本显示错误。当然,我正在搜索的模式在文件中。我得到的错误如下:无法读取文件“应该搜索的模式”:没有这样的文件或目录这是我的建议;不管问题是什么,它都回答了问题本身。你能给出变量
textToGrep
fileName
?以及文件的内容吗?你能给出变量
textToGrep
fileName
?以及file也是?谢谢你的回答。但我仍然得到相同的错误:无法读取文件“这是因为
在外壳上具有特殊意义。我已经用解决方案编辑了我的答案。谢谢你的回答。但我仍然得到相同的错误:无法读取文件”这是因为
在外壳上具有特殊的意义。我用解决方案编辑了我的答案。有没有一些方法可以从xml中删除grep之前的空格(尽管这与此问题无关)?你的意思是把空白删掉``使之成为
?我的意思是在属性之前删掉空白:所以我同意Hai Vu。我认为这是