【问题标题】:Tcl variables inside awk (using awk inside Tcl)awk 中的 Tcl 变量(在 Tcl 中使用 awk)
【发布时间】:2013-07-24 05:06:43
【问题描述】:

我需要在 Tcl 脚本中使用 awk 命令。我有一个如下文件。我们称之为 giri.txt

1  what
2  Why
3  When
4  who

我写了下面的代码,以为会这样打印:

what did
why did
when did
who did

set a did
exec cat giri.txt | awk {{ print $2 " " $a }}

但它会这样打印:

what what
why why
when when
who who

谁能解释一下为什么会这样打印?任何人都可以建议一种在 awk 中使用 Tcl 变量的方法吗?

【问题讨论】:

    标签: shell unix scripting awk tcl


    【解决方案1】:

    你也许可以在不调用 awk 的情况下解决所有 tcl 问题,但如果你真的想这样做:

    set a did
    exec awk "{print \$2, a}" a=$a < giri.txt
    

    如果您对如何扩展命令有疑问,请用 echo 替换 exec 并检查结果

    echo awk "{print \$2, a}" a=$a
    

    【讨论】:

    • 如果我们在 tcl 中使用 awk,相同的 shell awk 代码是否有效?或者它是 awk 的 tcl 版本?
    • exec创建了一个新进程
    • 如果我想在没有空格的情况下打印 $a 和 $2 怎么办?
    【解决方案2】:

    不使用 awk 即可:

    set a "did"
    set stream [open "giri.txt"]
    while {[gets $stream line] >= 0} {
      puts "$line $a"
    }
    close $stream
    

    使用可重复使用的程序会更好:

    proc forEachLine {file args} {
      set stream [open $file]
      while {[gets $stream line] >= 0} {
        {*}$args $line
      }
      close $stream
    }
    
    set a "did"
    forEachLine "giri.txt" apply {{line} {
      global a
      puts "$line $a"
    }}
    

    【讨论】:

    • 您给出的第一个代码只是逐行读取文件并将其与 $a 一起打印。它没有选择列。要使用类似于 awk 的操作,我们需要设置字段 [regexp -all -inline {\S+} $line] 之类的东西。使用 awk commad,我们可以用两行代码完成这一切,对吗?如果我们在 Tcl 中使用它,它是否有一些性能优势
    • @GIRIMURALI 更少的代码行并不意味着更少的执行时间,你必须测试性能差异。如果性能非常重要,请考虑使用 C。不过,我可以想到调用 awk 的许多其他缺点:您的脚本将使用两个进程而不是一个进程,这在进程数量有限的系统上并不好。您将很难调试两个进程。任何维护代码的人都需要知道 awk。不同系统上可能有不同版本的 awk,有时甚至根本没有 awk。
    猜你喜欢
    • 1970-01-01
    • 2019-08-21
    • 2015-07-20
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    相关资源
    最近更新 更多