【问题标题】:bash string expansion for grep -E expression in single quotes单引号中 grep -E 表达式的 bash 字符串扩展
【发布时间】: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 就可以了。祝你好运。

标签: bash grep


【解决方案1】:

为什么要添加单引号?只需删除此行:

 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

【讨论】:

  • 你说得对,这行得通。我添加它们是因为命令行需要它们。为什么有区别? (也非常感谢!这是我最终陷入与转义字符的泥潭直到忘记我尝试过的排列的那些事情之一......)
  • 在命令提示符下,单引号阻止管道用于重定向 I/O,但不会传递到 grep。当引号是变量值的一部分时,它们会在变量展开时传递(以及正则表达式的一部分)。
  • 在脚本开头添加命令set -x .. 这将指示 bash 向您展示它是如何扩展变量和启动子进程的。这是我一直用来调试这类问题的一个非常有用的技巧。
  • 您应该在变量引用周围使用双引号(例如 grep -q -E "$EXCLUDE_PATTERN"),因为 shell 会 some 解析替换值(只是不解析变量中的引号)价值)。在这种情况下,您可以不使用双引号,但最好养成在使用变量时使用双引号的习惯。
  • @stevesliva:它与 bash 解析命令行中各种元素的顺序有关。具体来说,它会在扩展变量之前解析引号,因此将引号 in 放在变量的值中并没有任何用处——当引号成为命令的一部分时,它们已经太迟了你的意思是他们。另一方面,将(双)引号围绕变量引用确实做了一些非常有用的事情。
猜你喜欢
  • 2015-05-06
  • 2018-04-16
  • 2023-02-23
  • 1970-01-01
  • 2019-12-28
  • 2016-09-29
  • 2012-01-25
  • 2015-02-28
  • 2021-09-07
相关资源
最近更新 更多