在tcl shell上找到带有“sed”的特定单词的行号

时间:2013-12-25 07:22:57

标签: sed cygwin tcl 32-bit

我需要从特定行开始搜索文件中的特定单词,并仅返回匹配行的行号。

假设我想在名为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
    }   
}
   }

仍无法找到解决问题的单行

有什么建议吗?

3 个答案:

答案 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。

更新2

我终于获得了访问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系统之间存在差异。

更新3

我在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以上的所有行