2013-11-01 79 views
0

我正在编写帮助我处理日志文件的脚本。其中,我有我的grep标志存储在一个变量。标志和字符串本身工作得很好,但是当我使用变量将它们传递给grep时,使用转义字符的字符串部分不会产生任何匹配。如下所示:当它们来自变量时,grep不匹配字符串

grepvars="-B4 -Psihe 'caused\sby|unable|fault|error|deadlock|checkpoint|corrupt|fail|exception|fatal|severe|\tat\s'" 
grep -B4 -Psihe 'caused\sby|unable|fault|error|deadlock|checkpoint|corrupt|fail|exception|fatal|severe|\tat\s' adapter_15.log > adapter_15-error1.log 
grep $grepvars adapter_15.log > adapter_15-error2.log 
wc -l *-error?.log 
    51398 adapter_15-error1.log 
    25032 adapter_15-error2.log 

正如您所看到的,\ tat \ s部分在通过变量传递给grep时不会产生匹配。应该匹配的是(字面空格)处的(字面标签)。虽然这可以在不使用变量的情况下正常工作,但我宁愿使用它,因为它使我的多个grep调用更易于管理。我需要做些什么来确保grep在通过变量传递时正确执行此匹配?

+0

如果您使用'egrep' /'grep -E'而不是? – fedorqui

+0

扩展变量时不处理引号。 – Barmar

+1

它适用于我,请使用grep -E或egrep – michael501

回答

1

在没有任何运气的情况下,我找到了一个解决方法:创建一个函数并在需要时调用它。这是我想到的:

grep4j() { 
unset IFS 
nice -n 15 grep -B3 -Psihe '\tat\s|caused\sby|unable|fault|error|deadlock|checkpoint|corrupt|fail|exception|fatal|severe' $1 
IFS=$'\n' 
} 

是的,我曾尝试在使用变量的grep字符串前后尝试取消设置IFS。它没有工作(我需要设置其他的东西来工作)。做这样的功能满足了我的需求,也许它也会帮助其他人。干杯!

如果您好奇,这是为了从log4j格式的日志中获取相关消息。这节省了我很多时间。

0

如果你存储在一个字符串的grep的所有选项,那么我想你需要使用邪恶eval

str="grep $grepvars adapter_15.log > adapter_15-error2.log" 
eval "$str" 
+1

删除圆括号 - eval是一个语句,而不是函数。 – Barmar

+0

@Barmar:谢谢,你说得对。我从JS的坏习惯,PHP到shell脚本我猜。 – anubhava

+1

@anubhava:谢谢,虽然这不是我选择的解决方案,但它指向了正确的方向,并给了我一个使用函数的想法。 – MrDrMcCoy

0

这可能是更容易的东西选择到环境变量GREP_OPTIONS和图案成一个文件,如下所示:

grep -f <file-with-patterns> ... 
+0

我试图避免外部文件依赖性,但如果必须,我会考虑这一点。 – MrDrMcCoy

相关问题