在 Tcl 中执行管道 shell 命令
Execute piped shell commands in Tcl
我想在 Tcl 中执行这些管道 shell 命令:
grep -v "#" inputfile | grep -v ">" | sort -r -nk7 | head
我试试:
exec grep -v "#" inputfile | grep -v ">" | sort -r -nk7 | head
并得到一个错误:
Error: grep: invalid option -- 'k'
当我尝试仅通过管道传输其中的 2 个命令时:
exec grep -v "#" inputfile | grep -v ">"
我得到:
Error: can't specify ">" as last word in command
更新:我还尝试了 {} 和 {bash -c '...'}:
exec {bash -c 'grep -v "#" inputfile | grep -v ">"'}
Error: couldn't execute "bash -c 'grep -v "#" inputfile | grep -v ">"'": no such file or directory
我的问题:如何在 tcl 脚本中执行初始管道命令?
谢谢
>
在这里引起了问题。
您需要将它从 tcl 和 中转义 shell 以使其在这里工作。
exec grep -v "#" inputfile | grep -v {\>} | sort -r -nk7 | head
或(这样更好,因为你少了一个grep
)
exec grep -Ev {#|>} inputfile | sort -r -nk7 | head
如果您查看您来自 运行 的目录(假设 tclsh
或类似),您可能会看到您创建了一个奇怪的文件(即 |
)之前。
在纯 Tcl 中:
package require fileutil
set lines {}
::fileutil::foreachLine line inputfile {
if {![regexp #|> $line]} {
lappend lines $line
}
}
set lines [lsort -decreasing -integer -index 6 $lines]
set lines [lrange $lines 0 9]
puts [join $lines \n]\n
(-double
可能比 -integer
更合适)
编辑: 我在编写(基于 0 的)[=15] 时错误翻译了命令 sort
的(基于 1 的)-k
索引=] lsort
的选项。现在已更正。
文档:fileutil package, if, join, lappend, lrange, lsort, package, puts, regexp, set
问题是 exec
在看到 >
本身(或在单词的开头)时会做“特殊事情”,因为这表明重定向。不幸的是,没有实际的方法可以直接避免这种情况;这是 Tcl 语法系统无能为力的领域。你最终不得不做这样的事情:
exec grep -v "#" inputfile | sh -c {exec grep -v ">"} | sort -r -nk7 | head
您还可以将整个管道移动到 Unix shell 端:
exec sh -c {grep -v "#" inputfile | grep -v ">" | sort -r -nk7 | head}
虽然坦率地说,这是您可以在纯 Tcl 中完成的事情,然后它也可以移植到 Windows…
我想在 Tcl 中执行这些管道 shell 命令:
grep -v "#" inputfile | grep -v ">" | sort -r -nk7 | head
我试试:
exec grep -v "#" inputfile | grep -v ">" | sort -r -nk7 | head
并得到一个错误:
Error: grep: invalid option -- 'k'
当我尝试仅通过管道传输其中的 2 个命令时:
exec grep -v "#" inputfile | grep -v ">"
我得到:
Error: can't specify ">" as last word in command
更新:我还尝试了 {} 和 {bash -c '...'}:
exec {bash -c 'grep -v "#" inputfile | grep -v ">"'}
Error: couldn't execute "bash -c 'grep -v "#" inputfile | grep -v ">"'": no such file or directory
我的问题:如何在 tcl 脚本中执行初始管道命令?
谢谢
>
在这里引起了问题。
您需要将它从 tcl 和 中转义 shell 以使其在这里工作。
exec grep -v "#" inputfile | grep -v {\>} | sort -r -nk7 | head
或(这样更好,因为你少了一个grep
)
exec grep -Ev {#|>} inputfile | sort -r -nk7 | head
如果您查看您来自 运行 的目录(假设 tclsh
或类似),您可能会看到您创建了一个奇怪的文件(即 |
)之前。
在纯 Tcl 中:
package require fileutil
set lines {}
::fileutil::foreachLine line inputfile {
if {![regexp #|> $line]} {
lappend lines $line
}
}
set lines [lsort -decreasing -integer -index 6 $lines]
set lines [lrange $lines 0 9]
puts [join $lines \n]\n
(-double
可能比 -integer
更合适)
编辑: 我在编写(基于 0 的)[=15] 时错误翻译了命令 sort
的(基于 1 的)-k
索引=] lsort
的选项。现在已更正。
文档:fileutil package, if, join, lappend, lrange, lsort, package, puts, regexp, set
问题是 exec
在看到 >
本身(或在单词的开头)时会做“特殊事情”,因为这表明重定向。不幸的是,没有实际的方法可以直接避免这种情况;这是 Tcl 语法系统无能为力的领域。你最终不得不做这样的事情:
exec grep -v "#" inputfile | sh -c {exec grep -v ">"} | sort -r -nk7 | head
您还可以将整个管道移动到 Unix shell 端:
exec sh -c {grep -v "#" inputfile | grep -v ">" | sort -r -nk7 | head}
虽然坦率地说,这是您可以在纯 Tcl 中完成的事情,然后它也可以移植到 Windows…