我有一个包含以下内容的文件:
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[$EntryCount].log" | sed -e 's/^"//' -e 's/"$//' )
意思是我不能单引号。
grep -Fxq "$CurrentLog" "/usr/local/nagios/libexec/DAF-988e7506-36c3-47e3-8ef2-428309e2c7f7-670.log"
似乎我需要同时逃避'“和”\“。我怎么能在一个命令中执行此操作?我希望-F不要求我添加额外的转义?
答案 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 Duffy在comment中提醒我的那样,最好在作业周围使用单引号,因为您不需要扩展任何变量或命令替换:
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
)。其中一个可能就足够了,只需这样就可以大大简化代码的读取。