2016-08-15 41 views
0

我有一个包含一个文件:grep的字符串,从文件的报价不工作

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不会要求我增加额外的逃避?

+2

你可能会考虑通过http://shellcheck.net/运行的代码习惯的问题和固定它认定。一个没有引号的扩展(即''CurrentLog' vs'“$ CurrentLog”')几乎总是错误的。 –

+0

我会考虑自己的答案,但问题目前尚不完整,无法独立评估答案是否完全正确。您可能会考虑尝试添加一个最小的,完整的,可验证的示例(根据http://stackoverflow.com/help/mcve) - 这涉及的一部分是构建一个包含展示正确功能所需的所有内容的示例(无关-stage'/ usr/local/nagios'文件,例如使用但未显示;没有提及处理输出的日志,但未显示原始数据;等等),以及除去此类验证所需的任何内容*。 –

+0

...因为在这里,如果您只接受来自'jq'的内容正确处理的答案,那么您可以考虑提供一个JSON格式的原始输入示例,这样人们可以相应地做出回答。 –

回答

0

为了避免转义双引号和反斜线,你可以使用单引号周围的变量声明:

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' 

测试变量的内容:

declare -p CurrentLog 
declare -- 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" 

然后用它作为:

grep -qFx "$CurrentLog" file && echo "matched" || echo "nope" 

matched 

另一种方法是使用here-doc来声明你的变量而不用担心引用:

read -r CurrentLog <<-'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 

,更宜避免创建一个单独的变量和使用过程中替代:

read -r CurrentLog < <(jq -r --arg EntryCount "$EntryCount" '.entries[$EntryCoun‌​‌​‌​‌​t | tonumber].log' <<< "$OutputTail") 
+0

嘿,我不能把我的CurrentLog单引号,因为我得到这样的值: CurrentLog = $(echo $ OutputTail | jq“.entries [$ EntryCount] .log”| sed -e's/^“ //'-e's /“$ //') – willemdh

+0

@willemdh:在这种情况下,使用here-doc,因为我建议使用 – anubhava

+1

@willemdh,是的,如果您正在分配的话,单引号建议是(完全正确的)一个常量字符串,这就是你在问题中表现出来的。 –

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匹配:

grep -F -f file-containing-pattern-line file-to-be-searched … 

然后,您不必打击shell的引用和转义机制(或者至少只在创建file-containing-pattern-line时)。还有'完整匹配整行'的-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)。其中之一可能就足够了,而且这样做的匹配大大简化了代码的阅读。

+3

如果使用单引号分配给'CurrentLog',那么将会有相当少的打斗。 –

+0

@CharlesDuffy:是的,也是! –

+0

由于日志不一定以日期开始,因此我无法剪切文本。 – willemdh