使用 AWK 减去时间
我想要实现的是第 1 章开始时间和第 2 章开始时间之间的差异,依此类推,从数组中的下一章开始时间减去每个章节开始时间,例如 00:05:57 - 00:01:03 = 00:04 :54
$ cat ChapterStart
00:00:00 00:01:03 00:05:57 00:08:27 00:11:58 00:14:50 00:20:19 00:25:06 00:33:17 00:38:21 00:42:30 00:46:11 00:51:33 01:00:04 01:00:56 01:04:15 01:09:13 01:16:51 01:20:03 01:27:58
这根本行不通:
#!/bin/bash
awk 'BEGIN{
{
for(i=1;i<=NF;i++){
m=split($i,t,":")
n=split($(i+1),w,":")
chap = (t[1]*3600) + (t[2]*60) + t[3]
chap_next = (w[1]*3600) + (w[2]*60) + w[3]
duration = (chap_next - chap)
print $duration
}
}
}'ChapterStart
有什么建议吗?
What I'm trying to achieve is the difference between chapter 1 start time and chapter 2 start time and so on subtracting each chapter start time from the next in the array e.g. 00:05:57 - 00:01:03 = 00:04:54
$ cat ChapterStart
00:00:00 00:01:03 00:05:57 00:08:27 00:11:58 00:14:50 00:20:19 00:25:06 00:33:17 00:38:21 00:42:30 00:46:11 00:51:33 01:00:04 01:00:56 01:04:15 01:09:13 01:16:51 01:20:03 01:27:58
This simply doesn't work:
#!/bin/bash
awk 'BEGIN{
{
for(i=1;i<=NF;i++){
m=split($i,t,":")
n=split($(i+1),w,":")
chap = (t[1]*3600) + (t[2]*60) + t[3]
chap_next = (w[1]*3600) + (w[2]*60) + w[3]
duration = (chap_next - chap)
print $duration
}
}
}'ChapterStart
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是您在
BEGIN
块中运行整个过程,因此它永远看不到数据。只需删除“BEGIN{”和最后一个“}”,它就应该可以正常工作。BEGIN
块在读取任何数据之前运行,并用于初始化。 awk 程序结构如下所示(BEGIN
,主数据循环 - 由一个或多个块组成 - 和END
都是可选的):主循环中的程序块可以有各种条件表达式、正则表达式或模式来选择是否执行它们。
另外,您的循环需要在最后一个字段之前停止,因为它无法获取最后一个字段之后的下一个字段:
除非您删除美元符号,否则这一行将不起作用:
因为您没有对返回值执行任何操作
split
您可以消除变量分配或重用变量:或者
此外,当您发布问题“不起作用”时,信息量并不大。
The problem is that you're running the whole thing in a
BEGIN
block so it never sees the data. Just remove "BEGIN{" and the last "}" and it should work fine.The
BEGIN
block is run before any data is read and is used for initialization. Awk program structure looks like this (BEGIN
, the main data loop - consisting of one or more blocks - andEND
are each optional):The program blocks in the main loop can have various condional expressions, regular expressions or patterns that select whether they are executed.
Also, your loop needs to stop before the last field since it can't get the next one after the last:
And this line won't work unless you remove the dollar sign:
Since you're not doing anything with the return values of
split
you can eliminate the variable assignment or reuse the variable:or
Also, when you post a question "doesn't work" isn't very informative.
正确的代码应该是
在 awk 读取输入文件之前处理 BEGIN 块。因此,如果您将代码放在 BEGIN 块内,则该文件将不会被处理。
the correct code should be
The BEGIN block is processed before the input file is read by awk. Therefore if you put your code inside BEGIN block, the file will not be processed.
你当然是对的。也许最好说“什么也不做”,这会非常准确,因为实际上什么也没发生。 =)
谢谢你们俩。
虽然我还没有完全理解 awk 的许多神秘方式,但我确实找到了一个更简单的(对我来说)解决方案,并在这个过程中学到了一些东西。这可行,但肯定可以做得更好。
You are of course correct. Perhaps it would have been preferable to have said "does nothing" which would have been quite accurate because exactly nothing happened. =)
Thanks to both of you.
While I still have not fully come to understand the many mysterious ways of awk I did find a simpler (to me) solution and learned a fair bit in the process. This works but surely could be done better.
其他解决方案仍然一遍又一遍地重新分割相同的列。该方法一次性分割整个输入,假设每个值都是正确的
HH:MM:SS
,然后从左到右迭代它们,并将每个chap_next
保存为下一个周期的chap
:事实上,您甚至可以直接读出
HH
、MM
、SS
的原始值,按照适当的顺序,因为The other solutions are still re-splitting the same columns over and over again. The approach splits the entire input all at once, assuming every value is a proper
HH:MM:SS
, then iterate them left-to-right, and saving eachchap_next
as next cycle'schap
:in fact, you can even directly read out the original values for
HH
,MM
,SS
, in proper order, since