在bash脚本中,我正在尝试为grep -E
构建一个字符串,使其显示为
grep -E 'alice|bar|bob|foo'
如果我在命令行测试grep-- ls * | grep -E 'alice|bar|bob|foo'
- 事情按预期工作。它排除了与扩展正则表达式中列表同名的所有文件。
我发现的问题是,如果我将字符串构造为'alice|bar|bob|foo'
破损的测试用例:
#!/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 "Excluding files that match the string $EXCLUDE_PATTERN" for file in *.tmp do if echo $file | grep -q -E $EXCLUDE_PATTERN then echo "Keeping $file" else echo "Deleting $file" rm -f $file fi done
输出:
Excluding files that match the string 'alice|bar|bob|foo' Deleting alice.tmp Keeping bob.tmp Deleting crump.tmp Deleting dammitall.tmp Deleting foo.tmp
...但我不想删除alice.tmp或foo.tmp,因为它们在正则表达式中!
我假设shell正在获取一些字符,当字符串在此脚本中展开时它不是,但我不能在我的生活中弄清楚传递给grep -E
的字符串是以什么方式被软化通过上面的“破碎”脚本。
EXCLUDE_PATTERN="'$EXCLUDE_PATTERN'"
等变体似乎没有帮助。没找到魔法弦。
修改以在下方添加有用的评论:
使用set -x
表示bash执行单引号包装本身,因此上面的错误代码会执行此EXCLUDE_PATTERN=''\''alice|bar|bob|foo'\'''
,这只是在单引号周围添加单引号。
答案 0 :(得分:3)
为什么要添加单引号?只需删除此行:
EXCLUDE_PATTERN="'""$EXCLUDE_PATTERN""'"
我没有那条线就得到了以下内容:
Excluding files that match the string alice|bar|bob|foo
Keeping alice.tmp
Keeping bob.tmp
Deleting crump.tmp
Deleting dammitall.tmp
Keeping foo.tmp