我需要从特定行开始搜索文件中的特定单词,并仅返回匹配行的行号。
假设我想在名为myfile
的文件中搜索单词my_word
,然后存储返回的行号。
使用shell脚本命令:
sed -n '10,$ { /$my_word /= }' $myfile
工作正常,但如何在tcl shell上编写该命令?
% exec sed -n '10,$ { /$my_word/= }' $file
关闭后的额外字符。
我想补充一点,以下命令在tcl shell上工作正常,但它从文件的开头开始
%exec sed -n“/ $ my_word / =”$ file
447431 447445 448434 448696 448711 448759 450979 451006 451119 451209 451245 452936 454408
我已解决了以下问题
set lineno 10
if { ! [catch {exec sed -n "/$new_token/=" $file} lineFound] && [string length $lineFound] > 0 } {
set lineNumbers [split $lineFound "\n"]
foreach num $lineNumbers {
if {[expr {$num >= $lineno}] } {
lappend col $num
}
}
}
仍无法找到解决问题的单行
有什么建议吗?
答案 0 :(得分:3)
我不明白一件事:您要查找的文字是存储在名为my_word
的变量中还是文字值my_word
?
在你的行
% exec sed -n '10,$ { /$my_word/= }' $file
我说它是第一个案例。所以你之前有类似
的东西% set my_word wordtosearch
% set file filetosearchin
您的错误是使用单引号字符'
来包含sed表达式。该字符是sh
中的封闭运算符,但在Tcl中没有意义。
您在sh
中使用它来将单个参数中的多个单词分组并传递给sed
,因此您必须执行相同操作,但使用Tcl语法:
% set my_word wordtosearch
% set file filetosearchin
% exec sed -n "10,$ { /$my_word/= }" $file
在这里,您使用"..."
进行分组。
您无法逃避$
中的$my_word
,因为您希望$my_word
替换为字符串wordtosearch
。
我希望这会有所帮助。
答案 1 :(得分:0)
经过几次试错后我想出了:
set output [exec sed -n "10,\$ \{ /$myword/= \}" $myfile]
# Do something with the output
puts $output
关键是要转义特殊于TCL的字符,例如美元符号,花括号。
Per Donal Fellows,我们不需要逃避美元符号:
set output [exec sed -n "10,$ \{ /$myword/= \}" $myfile]
我尝试了新版本并发现它有效。谢谢你,Donal。
我终于获得了访问Windows 7机器的权限,安装了Cygwin(包括sed和tclsh)。我尝试了上面的脚本,它工作得很好。我不知道你的问题是什么。有趣的是,我的Mac OS X系统上的相同脚本失败,出现以下错误:
sed: 1: "10,$ { /ipsum/= }": extra characters at the end of = command
while executing
"exec sed -n "10,$ \{ /$myword/= \}" $myfile"
invoked from within
"set output [exec sed -n "10,$ \{ /$myword/= \}" $myfile]"
(file "sed.tcl" line 6)
我猜Linux和BSD系统之间存在差异。
我在Linux / Tcl 8.4下尝试了相同的脚本,但它确实有效。这可能意味着Tcl 8.4与它无关。以下是其他可能有用的内容:Tcl附带了一个名为fileutil
的包,它是 tcllib 的一部分。 fileutil
包中包含适用于此案例的有用工具:fileutil::grep
。以下是有关如何在您的案例中使用它的示例:
package require fileutil
proc grep_demo {myword myfile} {
foreach line [fileutil::grep $myword $myfile] {
# Each line is in the format:
# filename:linenumber:text
set lineNumber [lindex [split $line :] 1]
if {$lineNumber >= 10} { puts $lineNumber}
}
}
puts [grep_demo $myword $myfile]
答案 2 :(得分:-1)
以下是awk
awk 'NR>10 && $0~f {print NR}' f="$my_word" "$myfile"
搜索包含变量10
$my_word
中的单词的行号myfile
以上的所有行