【问题标题】:Escaping asterisks and other special characters in shell script在 shell 脚本中转义星号和其他特殊字符
【发布时间】:2012-03-25 14:24:10
【问题描述】:

我需要逐行读取文件并构造一个管道 grep 语句以使用 -v 标志消除这些模式,即我有一个文件,比如说 negativelist,它包含以下模式:

Hello
World
Java

因此,我逐行读取此文件并按如下方式构造管道 grep 语句以从示例文件 inputfile

中消除这些模式

grep -v "Hello" 输入文件 | grep -v "世界" | grep -v "Java"

但是,我在否定列表中声明特殊字符时遇到了问题。虽然我通常会使用 grep -v '*' inputfile 来消除所有包含星号的行,但我似乎无法完成这项工作。在 negativelist 中用单引号转义星号似乎没有帮助。关于我应该如何转义星号以便能够消除包含它的行的任何想法,使用我目前使用双引号包围从 negativelist 读取的任何行的方法?

为了澄清,我有以下一组约束:

  • grep 管道字符串由以下形式的脚本构造: grep -v "line1 from negativelist" inputfile | grep -v "line2 from negativelist ... 以此类推
  • 此外,此脚本运行此 grep 命令并将其输出存储在另一个文件中。
  • 我只能通过定义 negativelist 中的模式来控制双引号之间的内容。我无法更改脚本生成这些管道 grep 语句的方式
  • 即使我认为我通过从命令行执行 grep "*" inputfile 来获得所需的输出,只是将 * 存储在 negativelist 中并不会产生所需的删除结果所有包含星号的行。
  • 进一步,定义诸如Hello.*World之类的模式来消除表单的所有行

    Hellotest1World,或

    Hellotest2World

negativelist 中定义时似乎不起作用,也可能星号未正确转义。命令行上的以下语句正常工作: grep -v "Hello.*World" inputfile ,即它正确地消除了所有包含 Hello 后跟任何字符的行,然后是 World

【问题讨论】:

    标签: regex shell grep


    【解决方案1】:

    您应该使用fgrep 而不是只使用grep,它会执行完全匹配而不扩展任何内容。

    例如:

    $ cat /tmp/a
    aaa
    zzz
    eee
    ***
    rrr
    ttt
    yyy
    
    $ fgrep -v -e 'aaa' -e '*' -e zzz -e yyy /tmp/a
    eee
    rrr
    ttt
    

    【讨论】:

    • 感谢您的建议。假设我不能使用 fgrep 作为构建这些管道语句的脚本不是我可以控制的,您还有其他建议吗?
    • 帖子已编辑。你控制什么? grep 也可以这样使用:grep '\*'
    • 生成管道 grep 语句的脚本实际上用双引号将 negativelist 中的每一行括起来。考虑到这个约束,我应该如何在 negativelist 中声明星号?
    • 我只控制负面清单的内容。所以我必须以某种形式避开星号。
    • 使用 fgrep 的 -f 选项来指定一个包含要匹配(或不匹配,在这种情况下)的列表的文件,而不是几个 -e。另请注意,fgrep(或等效的 grep -F)不会以任何特殊方式处理“*”。这只是一个角色。固定字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多