带文件无效的引号的grep字符串

时间:2016-08-15 20:05:04

标签: bash sed grep escaping

我有一个包含以下内容的文件:

2016-08-15 21:02:59,007: 233-670-rundeck-dispatch-script.tmp.sh: Info: Arg: -H server -S SrvCtrl,SNMP -A \"restart\" -CS \"Undefined\" -RS \"Undefined\" -CT \"Undefined\" -RT \"Undefined\" --LogServer logserver:5610

当我试图拖尾执行日志时,我正在检查日志文件是否包含最新的日志。并查看此字符串是否存在。我尝试使用grep -F,grep -E,grep -FFxq 简而言之,它归结为:

CurrentLog="2016-08-15 21:02:59,007: 233-670-rundeck-dispatch-script.tmp.sh: Info: Arg: -H server -S SrvCtrl,SNMP -A \"restart\" -CS \"Undefined\" -RS \"Undefined\" -CT \"Undefined\" -RT \"Undefined\" --LogServer logserver:5610"

请注意,CurrentLog填充如下:

CurrentLog=$(echo "$OutputTail" | jq ".entries[$EntryCoun‌​t].log" | sed -e 's/^"//' -e 's/"$//' ) 

意思是我不能单引号。

grep -Fxq "$CurrentLog" "/usr/local/nagios/libexec/DAF-988e7506-36c3-47e3-8ef2-428309e2c7f7-670.log"

似乎我需要同时逃避'“和”\“。我怎么能在一个命令中执行此操作?我希望-F不要求我添加额外的转义?

1 个答案:

答案 0 :(得分:2)

反斜杠需要加倍;嵌入式双引号也需要转义(反斜杠)。因此,您最终会\\\"出现CurrentLog

CurrentLog="2016-08-15 21:02:59,007: 233-670-rundeck-dispatch-script.tmp.sh: Info: Arg: -H server -S SrvCtrl,SNMP -A \\\"restart\\\" -CS \\\"Undefined\\\" -RS \\\"Undefined\\\" -CT \\\"Undefined\\\" -RT \\\"Undefined\\\" --LogServer logserver:5610"

此外,正如Charles Duffycomment中提醒我的那样,最好在作业周围使用单引号,因为您不需要扩展任何变量或命令替换:

CurrentLog='2016-08-15 21:02:59,007: 233-670-rundeck-dispatch-script.tmp.sh: Info: Arg: -H server -S SrvCtrl,SNMP -A \"restart\" -CS \"Undefined\" -RS \"Undefined\" -CT \"Undefined\" -RT \"Undefined\" --LogServer logserver:5610'

显然,如果你简化了问题的字符串(例如server实际上是从一个变量扩展的话)那么你需要重新考虑这个。还要认真考虑.*的建设性用法,以匹配引用的内容。除了一个具有"restart"而另一个具有"Undefined"并且字符串中的同一点具有grep -F -f file-containing-pattern-line file-to-be-searched … 之外,您不可能拥有多个具有相同内容的日志。使用正则表达式是一种平衡相关内容和非相关内容的艺术。

但是有一点(在你到达这个状态之前的某个地方),除了要匹配到文件中的字符串并使用与grep匹配的文件和固定字符串之外,最好是这样:

file-containing-pattern-line

然后你不必打击shell的引用和转义机制(或者,至少,只有在你创建-x时)。还有cat > file-containing-pattern-line << 'EOF' 2016-08-15 21:02:59,007: 233-670-rundeck-dispatch-script.tmp.sh: Info: Arg: -H server -S SrvCtrl,SNMP -A "restart" -CS "Undefined" -RS "Undefined" -CT "Undefined" -RT "Undefined" --LogServer logserver:5610 EOF 选项'完全匹配整行'。

不要忘记这里带引号的文件不会被解释:

233-670-rundeck-dispatch-script.tmp.sh

您还应该考虑是否真的需要匹配所有这些。只是数据/时间足够,或者日期/时间加上脚本名称(mllib)。其中一个可能就足够了,只需这样就可以大大简化代码的读取。