Bash脚本新手求助:Linux下匹配含特殊字符的字符串失败
解决你的Awk日志匹配问题
嘿,我明白你作为Bash新手遇到的困扰——正则里的特殊字符确实很容易踩坑,你的问题正好出在这里。
问题根源
你写的第一个正则表达式/[c8d313c81caa1103:-603ec52f:1630466b4e8:5448][amirbekova] com.sas.analytics.crm.custdata.sql/有个关键错误:在Awk的正则语法里,[]是字符集的标记,不是字面意义上的方括号。而且里面的-会被解析成字符范围(比如a-z),这就导致你的正则根本不是在匹配那串完整的日志前缀,而是在匹配一堆零散的字符,自然永远触发不了flag=1,后续的CMDM.内容也就提取不到了。
两种解决方案
方案1:转义正则特殊字符
把所有有特殊含义的字符([、]、-)用\转义,让Awk把它们当作字面量处理。修改后的命令如下:
awk '/\[c8d313c81caa1103\:-603ec52f\:1630466b4e8\:5448\]\[amirbekova\] com.sas.analytics.crm.custdata.sql/{flag=1;next}/quit;/{flag=0}flag && /CMDM\./' SASMarketingAutomationCore5.4.log.2018-04-27 >> test1.txt
这里给每个[加了\[,每个]加了\],-也转成了\-,确保Awk完全按照你写的字符串去匹配前缀行。
方案2:用index()函数避免正则麻烦(更适合新手)
如果你不想纠结正则转义,Awk的index()函数可以直接匹配固定字符串,不需要考虑任何正则特殊字符,非常省心。修改后的命令:
awk 'index($0, "[c8d313c81caa1103:-603ec52f:1630466b4e8:5448][amirbekova] com.sas.analytics.crm.custdata.sql") != 0 {flag=1;next} index($0, "quit;") != 0 {flag=0} flag && index($0, "CMDM.") != 0' SASMarketingAutomationCore5.4.log.2018-04-27 >> test1.txt
index($0, "目标字符串")会返回字符串在当前行的起始位置,返回值不为0就说明行里包含这个字符串,逻辑和你原来的flag控制完全一致,但不用处理正则转义。
小测试技巧
你可以先单独测试前缀匹配是否生效,比如运行:
awk '/\[c8d313c81caa1103\:-603ec52f\:1630466b4e8\:5448\]\[amirbekova\]/' SASMarketingAutomationCore5.4.log.2018-04-27
如果能输出对应的日志行,说明前缀匹配没问题,再加上后续的flag和CMDM.过滤逻辑就可以正常工作了。
内容的提问来源于stack exchange,提问作者Oljas
相关产品推荐
相关产品推荐

