![带有意外标记的复杂 grep 正则表达式](https://linux22.com/image/1061842/%E5%B8%A6%E6%9C%89%E6%84%8F%E5%A4%96%E6%A0%87%E8%AE%B0%E7%9A%84%E5%A4%8D%E6%9D%82%20grep%20%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F.png)
我有一个 Magento 2 安装,我正在尝试查找任何语法不正确的 xml 文件。
我正在尝试使用以下命令在目录中查找code
包含标记resource
但缺少id
属性的节点的任何 acl.xml 文件。
我已经在在线正则表达式测试器上成功测试了此正则表达式代码:
<(?:resource)(?:\s+(?!id\b)[\w\-.:]+(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|[\w\-.:]+))?)*\s*/?>
但是,当我尝试使用以下命令时,出现错误:
find app/code -type f -name "acl.xml" | xargs ack '<(?:resource)(?:\s+(?!id\b)[\w\-.:]+(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|[\w\-.:]+))?)*\s*/?>'
-bash: syntax error near unexpected token `)'
知道为什么这个命令不起作用吗?
答案1
那里的正则表达式怪物包含单引号,它结束引用的字符串:
find ... '<(?:resource)...(?:"[^"]*"|\'[^\']*\'|[\w\-.:]+))?)*\s*/?>'
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^
反斜杠不可以转义单引号内的任何内容,因此标记的部分被引号括起来,而其外的内容则没有。如果存在特殊字符,shell 会感到困惑。(好吧,如果我尝试手动解析它,我会感到困惑。)
您至少可以通过改为双引号来解决这个问题,这样反斜杠就可以用来转义字符串中的双引号。
另一种方式是滥用命令替换和此处文档,这样应该能够处理引号而无需进一步转义:
$ string=$(cat <<'EOF'
!"#%&/()[]{}'-.,*
EOF
)
$ echo "$string"
!"#%&/()[]{}'-.,*