我希望使用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"
}
另外,如果搜索模式根本不匹配,则返回的值是:"child process exited abnormally"
下面是简单的测试用例:
set textToGrep "<BBB name=\"BBBRM\""
文件内容:
<?xml version="1.0"?>
<!DOCTYPE AAA>
<AAA>
<BBB name="BBBRM" />
</AAA>
发布于 2013-08-12 10:58:24
这里有两个问题:
child process exited abnormally
退出。第一个问题是,您没有将textToGrep
封装在double quotes
中(而不是单引号)。所以你的代码应该是:
[catch {exec grep -n "$textToGrep" $fileName} lineNumber]
第二个问题是由于grep
命令的退出状态。当找不到模式时,grep
会出现错误。下面是对外壳的尝试:
# 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 "<BBB name=\"BBBRM\""
regsub -all -- {<} "$textToGrep" "\\\<" textToGrep
regsub -all -- {>} "$textToGrep" "\\\>" textToGrep
发布于 2013-08-12 10:22:49
嗯,我也遇到了你的代码和一个单词模式的问题!
首先,我认为您不需要eval
命令,因为catch
本身对其第一个参数进行了计算。
然后,问题是您将$textToGrep
变量放入exec
中的单引号'
中,这对Tcl没有任何意义。
因此,如果textToGrep
的内容是foo
,则要求grep
搜索字符串'foo'
。如果该字符串(包括单引号)未在文件中找到,则会得到错误。
试着用
set status [catch {exec grep -n $textToGrep $fileName} lineNumber]
看看能不能用。另外,请阅读exec
手册页,它很好地解释了这些问题。
发布于 2013-08-12 14:22:08
如果您的系统有tcllib安装,可以使用来自fileutil
包的fileutil
命令:
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
}
讨论
textToGrep
时,我使用了大括号,从而允许内部引用双引号,而不必转义它们。::fileutil::grep
命令的结果是字符串的lits。每个字符串包含文件名、行号和行本身;用冒号分隔。lindex
获取第二项(index=1,因为列表是零基的)。https://stackoverflow.com/questions/18183901
复制相似问题