bash高效的文件解析

pik*_*wyn 1 bash performance awk parsing

我有以下格式的日志文件:

20:15:35 start opsdfslkdfflkjsdlkfjlsdkfj
20:17:21 lkjlkj lklkjlkjlkjlkjlkjlkjlkjlkj
.
.
.
20:34:11 end kljsdklasjdlaksjdasdasd
20:36:20 start lksadjlaskjdalksdj
.
.
etc
Run Code Online (Sandbox Code Playgroud)

在解析此文件的结果中,我希望在后续startend条目之间获得时间差异.为了保持一致性,它应该在bash中完成(其他日志解析在bash中完成+使用gnuplot绘图).但是通过将文件重定向到while循环然后使用例如awk将时间戳转换为秒来读取文件会使整个解析非常慢(可能是由于每行创建新的子进程).

while read line; do
    if [[ $string == *"start"* ]]
    then
        start=$(echo $line | awk '{print $1}' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
        echo $start
    fi
done <log.txt
Run Code Online (Sandbox Code Playgroud)

有什么想法如何在bash中有效地完成这项工作?

Cha*_*ffy 6

它比纯awk实例慢,但在本机bash中,只使用shell内置:

while IFS=': ' read -r hr min sec content; do
  if [[ $content = *"start"* ]]; then
    start=$(( hr * 3600 + min * 60 + sec ))
    echo "$start"
  fi
done <log.txt
Run Code Online (Sandbox Code Playgroud)

这也将在适当的David Korn ksh中运行得更快.(如果使用ksh克隆,例如mksh而不是合法文章,结果,特别是性能结果会有所不同).


或者,对于纯粹的awk,你可以避免while read在bash中有任何循环:

awk -F: '/start/ { print ($1 * 3600) + ($2 * 60) + $3 }' <log.txt
Run Code Online (Sandbox Code Playgroud)

在bash中实现整个事情(识别开始/结束对并打印增量)可能如下所示:

while IFS=': ' read -r hr min sec sigil rest; do
  case $sigil in
    start) start_sec=$(( hr * 3600 + min * 60 + sec )); end_sec= ;;
    end)   end_sec=$(( hr * 3600 + min * 60 + sec ))
           if [[ $start_sec ]]; then
             echo "$start_sec->$end_sec -- $(( end_sec - start_sec )) elapsed"
             start_sec=
           fi
           ;;
  esac
done <log.txt
Run Code Online (Sandbox Code Playgroud)

...或者,对于awk中的整个事情:

awk -F: '
  /start/ { start=( ($1 * 3600) + ($2 * 60) + $3 ) }
  /end/   { end=(   ($1 * 3600) + ($2 * 60) + $3 );
            if (start) {
              print start " -> " end " -- " (end - start) " elapsed"
              start=0
            }
          }
' <log.txt
Run Code Online (Sandbox Code Playgroud)

  • 我建议`/ ^ [^ [:space:]] + [[:space:]] + start [[:space:]] /`而不是`/ start /`,因为我们不知道还有什么在线上. (2认同)