从bash脚本中排除属性

时间:2014-08-06 10:29:01

标签: bash

我们假设我在这种层次结构中有几个文件夹:

/somewhere/firstDirectory
/somewhere/secondDirectory
/somewhere/DifferentOne
/somewhere/ImportantLogs
/somewhere/CFPC

(这里有很多不同的文件夹)

我想编写一个bash脚本,它将解析一定数量目录中的所有文件 在这些层次结构中,由于将部署的环境不同,这可能会有所不同。 脚本应检查的目录,其名称和文件内容可能会有所不同。

因此,我没有创建一个具有大量逻辑分支的通用脚本,而是开始意识到将更好的内容放在一起 进入属性文件,就像这些示例二:

env1.properties:
 $LOG_DIR="/somewhere/[firstDirectory,CFPC]"
 $MATCHING_PATTERN="ERROR.*"

env2.properties:
  $LOG_DIR="/somewhere/[ImportantLogs,DifferentOne,CFPC]"
  $MATCHING_PATTERN="ERROR.*((Parsing ERROR with reason)$"

然后我们有一个这样的脚本:

#!/bin/bash

. $CONFIG/common/error_mailer.properties

ENTRY_MAX_AGE=$(($MAX_AGE_IN_HOURS*60*60))
LOG_FILES=$(find $LOG_DIR -type f -name $FILE_PATTERN)
LINES_WITH_ERRORS=$(zegrep -h "$MATCHING_PATTERN" $LOG_FILES | awk -v max_age=$ENTRY_MAX_AGE 'BEGIN {FS="[:. ]"} {now=systime()} {then=mktime(20$3 " " $2 " " $1 " " $4 " " $5 " " $6); if((now-max_age)<=then) print $0}')

if [ ! -z "$LINES_WITH_ERRORS" ]
then
  COUNT=$(echo "$LINES_WITH_ERRORS" | wc -l )
  RESULT_TABLE=$(
    echo -e "$LINES_WITH_ERRORS" |
    sort |
    head -n $MAX_NUMBER_OF_ITEMS |
    gawk -vpattern="$MATCHING_PATTERN" 'BEGIN{printf "Date and Time\t\tError Item\\n"}  match($0, pattern, m){printf  $1 " " $2 "\t" m[1] ".\\n"}'
  )
  MESSAGE+="$COUNT\n\n"
  if [ $COUNT -ge $MAX_NUMBER_OF_ITEMS ]
  then
    MESSAGE+=$MAIL_SUMMARY_TRIM
  else
    MESSAGE+=$MAIL_SUMMARY
  fi
  MESSAGE+=$RESULT_TABLE
  MESSAGE+=$FOOTER
  SUBJECT="$TITLE - $TOTAL_NUMBER_MESSAGE$COUNT"
  MESSAGE=$(echo -e "$MESSAGE" | sed 's/$/\r/')
  echo -e "Sending message with subject '$SUBJECT' and body:\n$MESSAGE\n"
  echo -e "$MESSAGE" | mail -v -s "$SUBJECT" "$RECIPIENT_LIST"
else
  echo "Nothing to send"
fi

(TITLE,FOOTER,$ TOTAL_NUMBER_MESSAGE,MAIL_SUMMARY_TRIM对于解释此问题变量并不重要)

我想问一下,如果我尝试做的是正确的吗?或者它应该在bash中以不同的方式完成? 特别是那部分:$ LOG_DIR =“/ somewhere / [firstDirectory,CFPC]”对我来说有点可疑,因为我不知道如何优雅地传递我想要检查的文件夹。我找不到更好的方法 解决这个问题。如果您可以建议我如何提高脚本质量,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

你的通配符错了。在使用方括号的地方,你应该使用卷曲的。

但是,因为Bash不会在此上下文中执行大括号扩展,所以我会将变量更改为数组,然后相应地更改调用代码。

此外,您指定的变量不应该有美元符号。 (美元符号用于插值,即访问变量的值。)

LOG_DIRS=( /somewhere/{firstDirectory,CFPC} )
MATCHING_PATTERN="ERROR.*"

然后在您的主脚本中,将$LOG_DIR更改为"${LOG_DIRS[@]}"(请注意,我重命名了该变量以更好地反映其内容)。

grep及其变体使用的正则表达式中,尾随通配符是无用的;程序在每个输入行的任何位置查找模式。