单引号中的grep -E表达式的bash字符串扩展

时间:2015-02-11 01:23:53

标签: bash grep

在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 "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'\''',这只是在单引号周围添加单引号。

1 个答案:

答案 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