查找特定单词出现时带有“;sed”;关于tcl外壳

查找特定单词出现时带有“;sed”;关于tcl外壳,sed,cygwin,tcl,32-bit,Sed,Cygwin,Tcl,32 Bit,我需要在文件中从特定行开始搜索特定单词,并仅返回匹配行的行号 假设我想在名为myfile的文件中搜索单词myu-word,然后存储返回的行号 通过使用shell脚本命令: sed -n '10,$ { /$my_word /= }' $myfile 工作正常,但如何在tcl shell上编写该命令 % exec sed -n '10,$ { /$my_word/= }' $file 右大括号后的额外字符 我想补充的是,以下命令在tclshell上运行良好,但它从文件的开头开始 %exec

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

假设我想在名为
myfile
的文件中搜索单词
myu-word
,然后存储返回的行号

通过使用shell脚本命令:

sed -n '10,$ { /$my_word /= }' $myfile
工作正常,但如何在tcl shell上编写该命令

% exec  sed -n '10,$ { /$my_word/= }' $file
右大括号后的额外字符

我想补充的是,以下命令在tclshell上运行良好,但它从文件的开头开始

%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
    }   
}
   }
仍然找不到一条线来解决问题


有什么建议吗

awk 'NR>10 && $0~f {print NR}' f="$my_word" "$myfile"

搜索所有大于行号
10
且包含变量中单词的行
$my_word
存储在变量
myfile

中的文件名中的所有行
my_word
,我不明白一件事:您要查找的文本是否存储在变量中称为
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\u word
中转义
$
,因为您希望用字符串
$my\u word
替换
$my\u word


我希望这能有所帮助。

经过几次尝试和错误后,我想到了:

set output [exec sed -n "10,\$ \{ /$myword/= \}" $myfile]
# Do something with the output
puts $output
关键是转义TCL特有的字符,如美元符号、大括号

更新 根据Donal Fellows的说法,我们不需要逃避美元符号:

set output [exec sed -n "10,$ \{ /$myword/= \}" $myfile]
我试过这个新版本,发现它很有效。谢谢你,多纳尔

更新2 我最终获得了一台Windows7机器,安装了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下尝试过相同的脚本,它可以工作。这可能意味着TCL8.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]

不清楚您是要搜索
my\u word
还是要搜索存储在变量
$my\u word
中的值。在您的文本中,您确实提到搜索word
my_word
,并且在示例中您使用了
my_word
作为变量名。我正在搜索存储在$my_Words中的值感谢您的重播,但是这种语法可以在unix shell上使用,我需要一种在tcl sh%exec awk'NR>10&$0~f上工作的语法{print NR}'f=“$token”“$file”关闭大括号后的额外字符这是普通的
awk
,应该适用于几乎所有的
linux/unix
发行版。我不明白你说的是什么错了。请给出一个输出示例。
awk
是一个程序本身,只是将其值返回给shell(bash/tcl)ya Jotne你说得对你的命令“awk'NR>10&&$0~f{print NR}'f=“$token”“$file”以及我的sed命令“sed-n'10,${/$my_-word/=}'$myfile”在unix/linux shell上成功运行,但是要在tcl shell上编写这样的命令,你必须考虑tcl shell的“特殊字符”,我的问题是如何将您的命令或我的命令转换为tcl shell可以接受的命令。我已将我的问题编辑为在tcl shell上有一个工作命令,但它从文件的开头开始,而不是从特定的行开始抱歉,但OP询问如何执行她从tcl shell获得的
sed
命令,而不是如何执行该命令使用另一种脚本语言执行相同的任务。非常感谢Marco,我已经按照您的步骤进行了操作,但是我遇到了以下错误$tclsh%set my_word afe\u drx\u m0\u in afe\u drx\u m0\u in%set file dmodem\u default.v dmodem\u default.v%exec sed-n“10,\${/$my\u word/=}”$file/usr/bin/sed:-e expression#1,char 6:unknown命令:``我还想补充一点,我在CygwinI下使用tcl,我想我犯了一个错误:
{
}
不应该被转义。我现在正在编辑答案。相同的错误%exec-n“10,\${/$my\u word/=}”$file/usr/bin/sed:-e expression#1,char 6:unknown命令:``在
$
之前不需要反斜杠;它后面有一个空格,所以它不是特别的。谢谢Hai,但仍然没有在Cygwin下处理我的tcl shell。以下说明了我的路径….$tclsh%在afe\u drx\u m0\u中设置我的单词afe\u drx\u在%set file dmodem\u postroute中_default.v dmodem\u postroute\u default.v%exec sed-n“10,$\{/$my\u word/=\}”$file/usr/bin/sed:-e expression#1,char 6:未知命令:`\'%必须是Linux系统(Ubuntu 13.10)之间的一些差异还有Cygwin。很抱歉,我没有Windows机器来试用。@HaiVu:我同意。我的第一次尝试,与你的尝试相同,是在Linux上进行的。非常感谢Marco和Hai,我用一个变通方法编辑了我的问题以解决这个问题,仍然不是最佳的,但效果很好。请参阅我的更新2。我的代码似乎可以在Cy上运行