【问题标题】:How to grep exact matching special characters from file?如何从文件中grep精确匹配的特殊字符?
【发布时间】:2015-02-14 15:54:45
【问题描述】:

我有一个如下文件:

A   4   ab,cc,ab,bc
B   6   x,xx,y,%,%%,\,\\
AB  0   

我需要从文件的第三列中 grep 特殊字符并返回其对应的第一列。例如,我需要 grep '%' 它会返回 B(它对应的第一列)

我尝试过使用:

grep -w "%" file1

但它会同时返回 % 和 %% 。喜欢:

B   6   x,xx,y,%,%%,\,\\

其中 %,%% 突出显示。我只想 grep 搜索的确切单词/字符。在上述情况下,它应该只尝试查找 '%' 而不是 '%%'。这种方法适用于 grep 手册 grep -w 中的单词,当它找到包含形成整个单词的匹配的行时。

我也试过用它

grep -wP "%" file1

对于 Perl 类似的模式。但是什么都没有回。

谁能建议我如何 grep 精确匹配的特殊字符?然而,这并不能解决特殊字符“\”的问题。反斜杠可以转义和处理。但是对于其他特殊字符,我需要找到解决方案。


好的。在我的问题中需要稍作改动。根据我的问题,这里给出的所有答案都很棒并且效果很好。但也许我在这里错过了另一个要求。我的错。因为这里的所有解决方案都使用 '%' 作为测试参数,但 '%' 只是我的例子。我真正想要的是更多适用于所有单词/字符的通用解决方案。我举个例子。考虑下面的文件:

A   4   a    b,c            c,ab,bc
          ^          ^
          ^     couple of tabs here
      multiple spaces here
B   6   x,xx,y,%,%%,\,\\
AB  0 

我的意思是该文件可以包含任何类型的字符、单词(由单个/多个空格、制表符等分隔)以及任何特殊字符(包括单引号 (')、双引号 (" ), 反斜杠 ())。这三个需要特殊处理,因为它们是保留的。

我很抱歉之前错过了这部分,但我希望我在这里寻找的解决方案现在很清楚。

我会投票支持特殊字符的所有有效解决方案。但它不允许我(减少声誉)。但是会有一个通用的解决方案吗?或者我是否可以通过 shell 脚本中的一些 if 条件来分隔单词(字母和数字)和特殊字符?

提前致谢

【问题讨论】:

  • 你的预期输出是什么?

标签: regex linux perl shell grep


【解决方案1】:

awk

$ awk '/%/{print $1}' inputFile
B

要准确匹配文件中的%,您可以使用环视法

$ grep -o '(?<!%)%(?!%)' input
  • (?&lt;!%) 消极看后面。断言% 前面没有%

  • (?!%) 否定前瞻。断言% 后面没有%

【讨论】:

    【解决方案2】:

    您可以使用扩展匹配:

    $ grep -P '(?<=[\s|,])%(?=[,$])' file
    B   6   x,xx,y,%,%%,\,\\
                   ^
                   highlighted
    

    仅当它被空格或,, 或行尾包围时才会匹配。

    说明

    grep -P '(?<=[\s|,])%(?=[,$])'
    
    • -P 使 grep 使用扩展的 Perl 正则表达式。
    • (?&lt;=X) 表示:检查之前是否有X
    • [\s|,] 表示:空格字符或逗号。
    • (?=Y) 表示:检查匹配后是否有Y
    • [,$] 表示:逗号或行尾。

    【讨论】:

      【解决方案3】:

      使用 perl,并按行自动拆分 - 这会将空格上的字段拆分为零索引数组 @F。然后,如果第三个字段 ($F[3]) 与正则表达式模式匹配,我将打印第一个字段 ($F[0])

      使用否定字符类只匹配一个 % 被不是 % 的东西包围。如果您一直在寻找逗号分隔的字段,您可以匹配 on 。如果您不知道分隔符,许多其他答案已经为您提供了一些前瞻/后瞻表达式的示例

      $ perl -lane 'print $F[0] if $F[2] =~ "[^%]%[^%]" ' < file1 
      B
      

      【讨论】:

        【解决方案4】:

        从命令行使用 perl,

        perl -nE 'say /(\S+)/ if /%/' file
        

        【讨论】:

          【解决方案5】:

          您可以使用带有-P 参数的grep。

          $ grep -oP '^\S+(?=\s+\S+\s+\S*(?<!%)%(?!%)\S*)' file
          B
          

          例子:

          $ cat hi
          A   4   ab,cc,ab,bc
          B   6   x,xx,y,%,%%,\,\\
          AB  0   
          C   6   x,xx,y,%%
          $ grep -oP '^\S+(?=\s+\S+\s+\S*(?<!%)%(?!%)\S*)' hi
          B
          

          【讨论】:

            猜你喜欢
            • 2015-04-13
            • 1970-01-01
            • 1970-01-01
            • 2013-11-12
            • 2018-11-04
            • 1970-01-01
            • 2018-06-26
            • 1970-01-01
            • 2021-03-19
            相关资源
            最近更新 更多