在循环中使用getline

时间:2014-11-28 19:28:05

标签: awk while-loop

考虑这个脚本

#!awk -f
BEGIN {
  "date" | getline foo
  print foo
}

它将按预期打印当前日期。但是如果你把它放在循环中

#!awk -f
BEGIN {
  while (1) {
    "date" | getline foo
    printf "%s\r", foo
  }
}

它只是重复打印相同的日期。我想抓住外部 使用getlinesystem

循环命令

2 个答案:

答案 0 :(得分:5)

$ cat tst.awk
BEGIN {
    cmd = "date"
    while (!done) {
        if ( (cmd | getline foo) > 0 ) {
            print foo
            done = (++i == 5 ? 1 : 0)
        }
        else {
            done = 1
        }
        close(cmd)
    }
}
$ awk -f tst.awk
Fri, Nov 28, 2014  3:18:21 PM
Fri, Nov 28, 2014  3:18:21 PM
Fri, Nov 28, 2014  3:18:21 PM
Fri, Nov 28, 2014  3:18:21 PM
Fri, Nov 28, 2014  3:18:21 PM

或者如果您愿意(但这是一个潜在的无限循环):

BEGIN {
    cmd = "date"
    while ( (cmd | getline foo) > 0 ) {
        print foo
        close(cmd)
    }
}

这是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脚本(https://superuser.com/a/694393)正在执行的操作:

$ 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变量来调用如有必要,请再次约会。

哦,到底是什么:

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
        }
    }
}

答案 1 :(得分:3)

你需要关闭这个过程才能让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