【问题标题】:How to check test command in Unix如何在 Unix 中检查测试命令
【发布时间】:2015-08-27 07:02:41
【问题描述】:

我只是想检查alert.log 文件,如果它的单词 (line?ed.) 计数大于 4 并且其中有单词 Time,那么我会grep 仅适用于时间,它将打印最新的时间戳。但如果 Time 不存在,它应该打印当前日期。

我想在一个条件下检查字数和 grep 标准。

if [[ -s "${SCRIPT_PATH}/alert.log" ]]; then
    if test `cat alert.log | wc -l` -gt 4 ;    
    then
        if test -s `cat alert.log | grep -i Time`;            
        then
            cat alert.log | tail -r | grep -i Time > latest_time.out
            CURRENT_TIMESTAMP=`cat latest_time.out | head -1 | grep "Time:*" | cut -f2 -d":"`
            echo $CURRENT_TIMESTAMP
            rm alert.log
        fi         
    fi
else
    CURRENT_TIMESTAMP=$( date +%Y-%m-%d )
    echo $CURRENT_TIMESTAMP
fi

如果我执行这个脚本并且alert.log 不包含时间这个词,它应该打印当前时间戳,但它不起作用。而当我单独检查时,我发现`cat alert.log | wc -l` -gt 4,这部分不起作用。怎么了?

【问题讨论】:

  • 这是一个可怕的椒盐卷饼逻辑和useless use of cat。你能总结一下你的脚本应该做什么,或者发布一个bash -x跟踪你遇到问题的特定命令吗?
  • 用一个简单的 Awk 脚本替换第一个分支中的所有内容会更加简洁、易读、易理解和高效。如果有任何条件失败,请将其设为exit 1,以便您可以使用它而不是 test[[
  • 第一个条件查找$SCRIPT_PATH/alert.log,而后续条件缺少路径。除非您在该目录中运行,否则它们将引用不同的文件;在大多数地方,该文件将不存在。
  • 脚本将从日志所在的同一路径运行

标签: unix testing cat wc


【解决方案1】:

如果没有来自bash -x 的输出,就很难确切地说出了什么问题;但是下面的代码应该更有效地执行逻辑并且更惯用。

if CURRENT_TIMESTAMP=$(awk 'tolower($1) == "time:" { t=$2 }
      END { if (NR>4 && t) { print t } else { exit 1 } }' alert.log); then
    rm alert.log
else
    CURRENT_TIMESTAMP=$(date +%Y-%m-%d)
fi
# repeated echo refactored to be performed only once, after condition
echo "$CURRENT_TIMESTAMP"

Awk 脚本包含几个额外的假设——具体来说,Time: 标记将始终是该行的第一个标记,而日期戳将是该行的第二个标记。如果输入文件不存在,Awk 将失败;如果它包含四行或更少,或者不包含任何匹配项,则END 子句将exit 1 也向if 发出失败信号。 (如果输入文件不存在,Awk 会发出错误消息,但我通常会将其视为一项功能。如果您希望 Awk 安静运行,请添加标准错误重定向。awk '... stuff ...' alert.log 2>/dev/null

因为 awk 只遍历文件一次,所以该逻辑比您重复的 catgrepheadtail 逻辑更有效。 Awk 脚本的变量 t 的值将在每个新匹配项上被覆盖,因此打印的值将来自文件中的最后一个匹配项。

【讨论】:

    猜你喜欢
    • 2015-05-08
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2011-12-19
    相关资源
    最近更新 更多