1

任何人都知道更好的方法来做到这一点,如果它更快?目前在将高行每秒推送到此脚本时很慢:


#!/bin/bash

declare -A clientarray
file=$1
timer=$2
e=$(date --date "now +$timer second" +%s)

while read line
do

    if [ -n "${clientarray[$line]}" ]; then
            let "clientarray[$line]=clientarray[$line]+1"
            echo "$line: ${clientarray[$line]}"

    elif [ -z "${clientarray[$line]}" ]; then
            clientarray[$line]=1
            echo "$line: ${clientarray[$line]}"

    fi
    if [ $(date +%s) -gt $e ]; then
                    e=$(date --date "now +$timer second" +%s)

    fi
done < <(tail -F $file | gawk -F"]" '/]/ {print $1}')

这是行的示例:

someline]
someline2]
somethingidontwant
someline3]
somethingelseidontwant
someline4]

并调用脚本:

bash script.sh somelogfile.log 1

如果我在最后注释掉 if 逻辑,它会非常快,但速度会下降 2/3。用 pv 测试它:

(这与 if 逻辑有关):

ubuntu@myhost:~/graphs$ tail -F somelogfile.log | pv -N RAW -lc >/dev/null | 
                      > bash script.sh somelogfile.log 1 | pv -N SCP -lc >/dev/null

  RAW: 2.18k 0:00:16 [ 493/s ] [                 <=>                             ]
  SCP:  593 0:00:16 [ 150/s ] [             <=>                                  ]

(这是没有)

ubuntu@myhost:~/graphs$ tail -F somelogfile.log | pv -N RAW -lc >/dev/null |
                      > bash script.sh somelogfile.log 1 | pv -N SCP -lc >/dev/null

  RAW: 7.69k 0:00:15 [512/s] [                                     <=>           ]
  SCP:  7.6k 0:00:15 [503/s] [                              <=>                  ]

如果我在脚本或测试方面遗漏了什么,请告诉我,尤其是任何“DOH!”。我想在这一点上我会喜欢一个=)

4

2 回答 2

2

作为猜测,我会说最后一个if...fi块每次迭代都会添加两个非内置命令。循环中的其他所有内容都是 bash 内置函数,执行速度要快得多。有了它,您可以date在测试中调用 to,并在if. 此外,每次调用时date --date都必须解析和评估该表达式,考虑到的普遍性,这可能不是很快。如果我是你,我会尝试用一种脚本语言重新实现它,对日期/时间进行更多的本地处理:Perl、Ruby、Python,无论你喜欢什么。"now +$timer second"--date

您似乎也有一个错误:

if [ `date +%s` > $e ] ...

这说:执行命令date +%s并将其输出(例如12345)插入另一个命令[ 12345 > $e ](到目前为止一切都很好)。该命令说:使用两个参数 (和) 运行[内置命令,并将其标准输出流重定向到以(uh-oh)的值命名的文件。您可能想使用而不是此处。12345]$e-gt>

于 2012-04-26T18:23:10.753 回答
0

我不确定你在做什么$e,但你可以使用内置的 shell 打印当前日期,printf这比调用date. 子流程调用往往很昂贵。例如,如果您不在 glibc2 上,您可以执行以下操作:

printf '%(%+)T\n' -1

准确获取 date 命令的输出。%+glibc2 不支持,因此您可以构造与其他参数相同的东西,或类似的东西:

printf '%(%c %Z)T\n' -1

如果您需要以某种方式捕获和处理日期,那么您可能仍然需要使用 subshel​​l 调用,$()但很有可能它仍然比date.

于 2014-09-03T07:48:32.577 回答