Awk 在循环内部使用getline

Awk 在循环内部使用getline,awk,while-loop,Awk,While Loop,考虑一下这个脚本 #!awk -f BEGIN { "date" | getline foo print foo } 它将按预期打印当前日期。但是如果你把它放在一个循环中 #!awk -f BEGIN { while (1) { "date" | getline foo printf "%s\r", foo } } 它只是重复打印相同的日期。我想捕获外部数据 使用getline或system在循环中执行命令您需要关闭该进程以使awk再次生成它 BEGIN {

考虑一下这个脚本

#!awk -f
BEGIN {
  "date" | getline foo
  print foo
}
它将按预期打印当前日期。但是如果你把它放在一个循环中

#!awk -f
BEGIN {
  while (1) {
    "date" | getline foo
    printf "%s\r", foo
  }
}
它只是重复打印相同的日期。我想捕获外部数据
使用
getline
system

在循环中执行命令您需要关闭该进程以使awk再次生成它

BEGIN {
  while (1) {
    "date" | getline foo
    printf "%s\n", foo
    close("date")
  }
}
我预计您的原稿中的后续读取实际上在EOF上失败,并且未设置
foo

$ awk 'BEGIN {
  while (1) {
    print "ret: " ("date" | getline foo)
    printf "%s\n", foo
  }
}'
ret: 1
Fri Nov 28 15:17:07 EST 2014
ret: 0
Fri Nov 28 15:17:07 EST 2014
或者,如果您愿意(但这是一个潜在的无限循环):

这是GNU awk中的秒表:

$ cat tst.awk
/s/ { start = systime() }
/e/ { end = systime(); print "elapsed:", end - start, "secs\n" }
/x/ { exit }
$
$ awk -f tst.awk
s
e
elapsed: 2 secs

s
e
elapsed: 6 secs

x
下面是如何执行bash脚本()的操作:

$ cat tst.awk
BEGIN {
    cmd = "date +%s.%N"
    if  ( (cmd | getline x) > 0 ) {
        close(cmd)
        while ( (cmd | getline y) > 0 ) {
            close(cmd)
            printf "%s\r", y-x
            if (++i == 10) exit
        }
    }
}
$
$ awk -f tst.awk
$ 7176013
我不知道shell命令中的第二个
date
在做什么,但我认为您可以找出该部分并在awk中对其进行编码,或者设置
cmd2
变量以在必要时再次调用date

哦,真见鬼:

BEGIN {
    date_sN = "date +%s.%N"
    date_TN_start = "date +%T.%N -ud@"

    if  ( (date_sN | getline x) > 0 ) {
        close(date_sN)
        while ( (date_sN | getline y) > 0 ) {
            close(date_sN)
            date_TN = sprintf("%s%.11f", date_TN_start, y - x)
            if  ( (date_TN | getline d) > 0 ) {
                close(date_TN)
                printf "%s\r", d
            }
            if (++i == 10) exit
        }
    }
}

当您说“我想使用getline或system在一个循环中捕获外部命令”时,请您进一步澄清您的期望是什么?您使用
getline
处于危险境地,并且使用不当(请参阅)。请澄清您是尝试运行一次外部命令并捕获其输出的每一行,还是多次运行外部命令并每次捕获其输出的第一行或其他内容,并更新您的问题以显示示例输入(例如,您希望运行getline的文本)以及给定输入的整个命令的预期输出。改为这样做。现在我明白他所说的“相同日期”是什么意思了。投票表决。
$ cat tst.awk
BEGIN {
    cmd = "date +%s.%N"
    if  ( (cmd | getline x) > 0 ) {
        close(cmd)
        while ( (cmd | getline y) > 0 ) {
            close(cmd)
            printf "%s\r", y-x
            if (++i == 10) exit
        }
    }
}
$
$ awk -f tst.awk
$ 7176013
BEGIN {
    date_sN = "date +%s.%N"
    date_TN_start = "date +%T.%N -ud@"

    if  ( (date_sN | getline x) > 0 ) {
        close(date_sN)
        while ( (date_sN | getline y) > 0 ) {
            close(date_sN)
            date_TN = sprintf("%s%.11f", date_TN_start, y - x)
            if  ( (date_TN | getline d) > 0 ) {
                close(date_TN)
                printf "%s\r", d
            }
            if (++i == 10) exit
        }
    }
}