在每一行前面加上生成它所需的时间

Krz*_*soń 3 shell timestamps

我想要一个脚本,它将在 stdin 的每一行前面加上生成它需要多长时间的信息。基本上用于输入:

foo
bar
baz
Run Code Online (Sandbox Code Playgroud)

我想拥有

0 foo
10 bar
5 baz
Run Code Online (Sandbox Code Playgroud)

其中 10 是打印 foo 和打印 bar 之间经过的 10 秒,与 5 类似,打印 bar 后需要 5 秒才能打印 baz。

我知道有一个ts显示时间戳的实用程序,我知道https://github.com/paypal/gnomon,但我不想使用 javascript 来做到这一点。

是否有标准工具,或者我应该使用 awk 并进行处理?

Joh*_*024 5

假设生成输出的脚本称为generate。然后,显示生成每一行所需的秒数:

$ generate | ( t0=$(date +%s); while read -r line; do t1=$(date +%s); echo " $((t1-t0)) $line"; t0=$t1; done )
 2 foo
 0 foo
 5 foo
 3 foo
Run Code Online (Sandbox Code Playgroud)

分布在多行中的相同命令如下所示:

generate | ( t0=$(date +%s)
    while read -r line
    do
        t1=$(date +%s)
        echo " $((t1-t0)) $line"
        t0=$t1
    done
    )
Run Code Online (Sandbox Code Playgroud)

或者,为了方便起见,我们可以定义一个包含以下代码的 shell 函数:

timer() { t0=$(date +%s); while read -r line; do t1=$(date +%s); echo " $((t1-t0)) $line"; t0=$t1; done; }
Run Code Online (Sandbox Code Playgroud)

我们可以这样使用这个函数:

$ generate | timer
 0 foo
 2 foo
 4 foo
 3 foo
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • t0=$(date +%s)

    这会以自纪元以​​来的秒数捕获脚本开始时的当前时间。

  • while read -r line; do

    这将启动一个从标准输入读取的循环

  • t1=$(date +%s)

    这将捕获当前行被捕获的时间(以秒为单位)。

  • echo " $((t1-t0)) $line"

    这会打印出当前行花费的时间(以秒为单位)。

  • t0=$t1

    这将更新t0下一行。

  • done

    这标志着while循环的结束。


Kus*_*nda 5

trickle () {
    awk 'BEGIN { t = systime(); OFS="\t" }
               { print systime() - t, $0 }
               { t = systime()           }'
}
Run Code Online (Sandbox Code Playgroud)

这个小小的 shell 函数简单地包装了一个awk脚本(与 GNUawk和兼容mawk -Wi,但与 BSD兼容,awk因为它缺少systime())。它将输出每行输入,前缀为自最后一行输出以来的整秒数。第一行将以零为前缀。

测试:

$ { echo hello; sleep 2; echo world } | trickle
0       hello
2       world
Run Code Online (Sandbox Code Playgroud)

awk脚本显然也可以独立运行:

$ some_command | awk 'BEGIN{OFS="\t";t=systime()}{print systime()-t,$0;t=systime()}
Run Code Online (Sandbox Code Playgroud)

例如

$ { echo hello; sleep 2; echo world; } | awk 'BEGIN{OFS="\t";t=systime()}{print systime()-t,$0;t=systime()}'
0       hello
2       world
Run Code Online (Sandbox Code Playgroud)