【发布时间】:2015-02-11 01:23:52
【问题描述】:
在 bash 脚本中,我尝试为 grep -E 构造一个字符串,使其显示为
grep -E 'alice|bar|bob|foo'
如果我在命令行测试 grep--ls * | grep -E 'alice|bar|bob|foo'-- 事情会按预期工作。它排除所有与扩展正则表达式中的列表同名的文件。
我发现的问题是,如果我将字符串构造为'alice|bar|bob|foo',它将不匹配 bash 脚本中的第一个和最后一个字符串
损坏的测试用例:
#!/bin/bash touch foo.txt bar.txt alice.txt bob.txt touch alice.tmp bob.tmp foo.tmp crump.tmp dammitall.tmp EXCLUDE_PATTERN=$(echo *.txt | sed 's/\.txt /|/g' | sed 's/\.txt//') EXCLUDE_PATTERN="'""$EXCLUDE_PATTERN""'" echo "排除匹配字符串 $EXCLUDE_PATTERN 的文件" 对于 *.tmp 中的文件 做 如果回显 $file | grep -q -E $EXCLUDE_PATTERN 然后 echo "保留$文件" 别的 echo "删除$文件" rm -f $文件 菲 完毕输出:
排除匹配字符串'alice|bar|bob|foo'的文件 删除 alice.tmp 保留 bob.tmp 删除 crump.tmp 删除 dammitall.tmp 删除 foo.tmp...但我不希望它删除 alice.tmp 或 foo.tmp 因为它们在正则表达式中!
我假设 shell 正在获取一些字符,而不是在此脚本中扩展字符串时,但我无法终生弄清楚传递给 grep -E 的字符串以何种方式被上面的“损坏”脚本。
EXCLUDE_PATTERN="'$EXCLUDE_PATTERN'" 之类的变体似乎没有帮助。还没有找到魔法字符串。
编辑以在下面包含有用的评论:
使用set -x 表示 bash 会自行包装单引号,因此上面的错误代码会这样做 EXCLUDE_PATTERN=''\''alice|bar|bob|foo'\''',它只是在单引号周围添加单引号。
【问题讨论】:
-
shell 正在“看到”您的
|字符作为管道。使用if echo ... grep .. "$EXCLUDE_PAT"(注意你的var名称周围的dbl-quotes)。并且,不要打扰EX_PAT="'""$EX_PAT""'",只需一组 dbl-quotes 就可以了。祝你好运。