【问题标题】:Execute piped shell commands in Tcl在 Tcl 中执行管道 shell 命令
【发布时间】:2016-04-20 00:20:37
【问题描述】:

我想在 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 脚本中执行初始管道命令?

谢谢

【问题讨论】:

  • @Etan Reisne 我试过例如:> exec {grep -v "#" cg_metrics.rpt | grep -v ">"} 但我得到:错误:无法执行 "grep -v "#" cg_metrics.rpt | grep -v ">"":没有这样的文件或目录 谢谢
  • 仍然报错:>exec {bash -c 'grep -v "#" cg_metrics.rpt | grep -v ">"'}Error: couldn't execute "bash -c 'grep -v "#" cg_metrics.rpt | grep -v ">"'": no such file or directory

标签: shell tcl


【解决方案1】:

问题是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……

【讨论】:

    【解决方案2】:

    > 在这里引起了问题。

    您需要将它从 tcl shell 中转义以使其在此处工作。

    exec grep -v "#" inputfile | grep -v {\\>} | sort -r -nk7 | head
    

    或者(这样更好,因为你少了一个grep

    exec grep -Ev {#|>} inputfile | sort -r -nk7 | head    
    

    如果您查看运行它的目录(假设为 tclsh 或类似的目录),您可能会看到您之前创建了一个奇怪的命名文件(即 |)。

    【讨论】:

    • 这不会出错,但恐怕不起作用。它不会转义包含“#”或> 的行。确实如您所描述的那样创建了一个文件。谢谢
    • 你可能需要grep -E
    • 它适用于grep -E,您使用的是哪个版本的grep
    • 我使用的是 8.5 版
    【解决方案3】:

    在纯 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 更合适)

    编辑:在为lsort 编写(基于0)-index 选项时,我错误地翻译了命令sort 的(基于1)-k 索引。现在已更正。

    文档:fileutil 包,ifjoinlappendlrangelsortpackageputsregexpset

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多