从文件中读取行时,如果使用 bash 脚本找到与给定字符串匹配的内容,则需要打印上一行

从文件中读取行时,如果使用 bash 脚本找到与给定字符串匹配的内容,则需要打印上一行

我有一个文件file.txt,内容如下所示,有超过 10000 行。

Wed May 27 15:41:29 PDT 2020  
Entering directory : /aaa/bbb/ccc  
Wed May 27 15:42:30 PDT 2020  
Entering directory : /aaa/bbb/ccc/ddd  
Wed May 27 15:43:19 PDT 2020  
Entering directory : /aaa/bbb/ccc/ddd/eee  
Wed May 27 15:44:25 PDT 2020  
Leaving directory : /aaa/bbb/ccc/ddd/eee  
Wed May 27 15:45:37 PDT 2020  
Leaving directory : /aaa/bbb/ccc/ddd'  
Wed May 27 15:46:42 PDT 2020  
Leaving directory : /aaa/bbb/ccc    

需要做什么

需要根据进入和离开目录之前的时间戳打印出哪个目录花费了多少时间。

输出应该是

_Directory_ : `/aaa/bbb/ccc`  
_Time taken_ : `00:05:13`

该目录的输入时间是 : Wed May 27 15:41:29 PDT 2020,离开时间是 :Wed May 27 15:46:42 PDT 2020所以时间差就是输出。
同样,还需要打印其他实例的目录路径和时间差。

尝试在论坛搜索并得到,但并没有完全解决我的问题。虽然我不是 shell 脚本方面的专家。因此,如果有人可以帮助我获得输出,那就太好了。

谢谢

答案1

不是完整的答案,但基于sed文档如果你这样做

cat file.txt | sed -n 'N;l;D' | sed -n '/.*\/aaa\/bbb\/ccc\s*\$/p'

你会得到

Wed May 27 15:41:29 PDT 2020  \nEntering directory : /aaa/bbb/ccc  $
Wed May 27 15:46:42 PDT 2020  \nLeaving directory : /aaa/bbb/ccc$

如果您知道所有相关目录的完整路径(您必须对其进行循环),这可以简化问题。

不确定获取经过时间的日期算术,但如果您可以从上面提取日期,转换为 unix 时间(自 1970 年 1 月 1 日以来的秒数)可能是一个开始。例如

date -d "Wed May 27 15:41:29 PDT 2020" +%s

给出

1590619289

因此,如果在您的脚本中您可以将日期放入变量中(我将逐字执行)

ENTERDATE="Wed May 27 15:41:29 PDT 2020"
LEAVEDATE="Wed May 27 15:46:42 PDT 2020"

并将它们转换成unixtime

ENTERSECONDS=`date -d "$ENTERDATE" +%s`
LEAVESECONDS=`date -d "$LEAVEDATE" +%s`

您可以如下获取以秒为单位的持续时间

DURATION=$(($LEAVESECONDS - $ENTERSECONDS))

在这种情况下是

313

可能有一些可用的软件包可以更好地支持日期算术。

希望这可以帮助。

答案2

以下是如何使用 GNU awk 执行您想要的操作mktime()并对您的输入做出一些假设:

$ cat tst.awk
{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") }
sub(/^Entering directory : /,"") {
    enterSecs[$0] = epochSecs
    next
}
sub(/^Leaving directory : /,"") {
    deltaSecs = epochSecs - enterSecs[$0]
    delete enterSecs[$0]

    hrs  = int(deltaSecs / (60*60))
    mins = int((deltaSecs % (60*60)) / 60)
    secs = deltaSecs % 60

    printf "_Directory_ : `%s`\n", $0
    printf "_Time taken_ : `%02d:%02d:%02d`\n", hrs, mins, secs
    next
}
{
    gsub(/:/," ")
    mthNr = (index("JanFebMarAprmayJunJulAugSepOctNovDec", $2)+2) / 3
    epochSecs = mktime( sprintf("%04d %02d %02d %02d %02d %02d", $NF, mthNr, $3, $4, $5, $6) )
}

$ awk -f tst.awk file
_Directory_ : `/aaa/bbb/ccc/ddd/eee`
_Time taken_ : `00:01:06`
_Directory_ : `/aaa/bbb/ccc/ddd`
_Time taken_ : `00:03:07`
_Directory_ : `/aaa/bbb/ccc`
_Time taken_ : `00:05:13`

相关内容