【问题标题】:bash: grep exact matches based on the first columnbash:基于第一列的 grep 完全匹配
【发布时间】:2013-06-11 04:53:33
【问题描述】:

我有一个 .txt 文件,如下所示:

9342432_A1 9342432 1 0 0 0
4392483_A2 4392483 2 0 0 0 
4324321_A3 4324321 1 0 0 0
9342432    9342432 2 0 0 0

例如,我想生成一个 ID 为 4324321_A3 和 9342432 的子集(基于第一列!)。 我尝试了以下命令来查找完全匹配:

 grep -E '4324321_A3|9342432'

但是当我使用这条线时,我最终得到了一个这样的数据集:

9342432_A1 9342432 1 0 0 0
4324321_A3 4324321 1 0 0 0
9342432    9342432 2 0 0 0

问题是与 ID (9342432_A1) 的一部分匹配的行不应该存在。 谁能帮我解决这个问题?

我想这样结束:

4324321_A3 4324321 1 0 0 0
9342432    9342432 2 0 0 0

【问题讨论】:

    标签: linux shell command-line grep


    【解决方案1】:

    当您需要匹配文件的特定字段(或列)时,最好使用awk 之类的工具,而不是grep。你可以这样写:

    awk '$1 == "STRING_TO_MATCH"' txtfile.txt
    

    这也适用于与第一列不同的列(只需将 $2 用于第二列,$3 用于第三列,依此类推)。
    awk 接受正则表达式和 grep。

    问候。

    【讨论】:

      【解决方案2】:

      您的正则表达式不会检查 ID 是否位于行首。只需在正则表达式的开头包含 ^ 以告诉它仅匹配行首的 ID,然后使用 () 对备选方案进行分组:

      grep -E '^(4324321_A3|9342432)\b' <file>
      

      \b 是一个边界字符,强制它只匹配整个单词。

      【讨论】:

        【解决方案3】:

        在每个模式的开头添加一个行首锚点和一个单词边界

        grep -E '^4324321_A3\b|^9342432\b'
        

        【讨论】:

          【解决方案4】:

          匹配

          9342432_A1 9342432 1 0 0 0
          

          因为它在第二列中有9342432

          您需要更新命令以使 grep 检查以这些单词开头的行,即使用^word

          $ grep -E '^4324321_A3|^9342432' file
          4324321_A3 4324321 1 0 0 0
          9342432    9342432 2 0 0 0
          

          为了更准确,您还可以使用匹配完整单词的-w。这样grep -wE '^4324321_A3|^9342432' file 不会匹配像

          这样的行
          4324321_A3something 4324321 1 0 0 0
          

          【讨论】:

            【解决方案5】:

            在您的 grep 中包含开头的 ^ 和模式后的空格

            【讨论】:

              猜你喜欢
              • 2010-12-03
              • 1970-01-01
              • 1970-01-01
              • 2018-02-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-02-13
              • 2015-07-02
              相关资源
              最近更新 更多