【问题标题】:How to grep the exact match and print only that match如何grep精确匹配并仅打印匹配
【发布时间】:2021-03-19 12:48:32
【问题描述】:

我有大量的数据文件,需要按以下格式打印确切的关键字:Filename : Keyword : line number

[注意:需要递归搜索整个目录的关键字]

例如:我要搜索关键字:abcxyz

文件中的数据如下所示

abcxyz.fgh

gfhj.abcxyz

i have a book with name abcxyz.sh

where is my brother called : abcxyz.fsdghj raju how are you 

afsgdjj kllf

ghjakl  ra jksu ldlahlalfb  afhkflkaf dbllf jll  afl;bnhafl

当我使用以下命令时:grep "abcxyz" *.* 它正在打印我不需要的整行

预期输出:

Filename : abcxyz.fgh    : line number 
Filename : gfhj.abcxyz   : line number
Filename : abcxyz.sh     : line number
Filename : abcxyz.fsdghj : line number 

【问题讨论】:

    标签: shell awk grep


    【解决方案1】:

    给你

    grep -roHn "\S*Your_text_here\S*" *

    标签

    -r : 在目录中递归

    -o : 只有匹配的部分

    -H : 带文件名

    -n : 带行号

    然后使用 \S 调整正则表达式以包含除空格、制表符和换行符之外的所有字符。 注意:如果您只想要字母和数字而没有特殊符号,请改用\w

    然后是最后的“*”,表示搜索当前目录中的每个文件和文件夹。所以要先用这个命令cd到需要的目录。

    【讨论】:

    • 有趣的是,您对问题的解释与我的做法相反。我可以理解。我们的答案之一可能不是 OP 想要的。我完全确信我的阅读能力。但可能你也是。让我们看看。
    • 看来您没看错。玩得开心。
    • 为什么你使用*作为路径,而不是.作为简单的“这里”?
    • 我习惯使用*。我通常需要选择具有特定格式的文件,例如“*.txt”。 . 完全适用于这种情况。
    • 您应该使用 \S 而不是 \w 因为 OP 想要匹配的不仅仅是单词组成字符,例如.,查看预期输出。您还应该提到这需要 GNU grep。
    【解决方案2】:

    这应该是awk 的工作,请您尝试使用GNU awk 中的示例进行跟踪、编写和测试。请提及绝对路径来代替 . 以在 find 命令中为任何目录运行它。

    所有文件的输出应为filename : matched string(s) : line number

    您可以按照find 命令运行:

    find . -type f -exec awk -f script.awk {} +
    

    其中script.awk如下:

    cat script.awk
    BEGIN{ OFS=" : " }
    NF{
      val=""
      for(i=1;i<=NF;i++){
        if($i~/abcxyz/){
          val=(val?val OFS:"")$i
        }
      }
      if(val){
        print FILENAME,val,FNR
      }
    }
    

    对于您显示的示例(考虑其中的空行),示例输出如下。

    Input_file  :  abcxyz.fgh     :  1
    Input_file  :  gfhj.abcxyz    :  3
    Input_file  :  abcxyz.sh      :  5
    Input_file  :  abcxyz.fsdghj  :  7
    

    说明:为上述添加详细说明。

    BEGIN{ OFS=" : " }              ##Setting OFS to space colon space in BEGIN section of this program.
    NF{                             ##Checking condition if line is NOT empty then do following.
      val=""
      for(i=1;i<=NF;i++){           ##Traversing through all field values here.
        if($i~/abcxyz/){            ##checking condition if field is matching abcxyz then do following.
          val=(val?val OFS:"")$i    ##Creating val which has value of current field and keep adding it.
        }
      }
      if(val){                      ##Checking condition if val is NOT NULL then do following.
        print FILENAME,val,FNR      ##Printing FILENAME val and FNR here.
      }
    }
    ' 
    

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 2012-09-22
      • 1970-01-01
      • 2013-11-19
      • 2012-11-23
      • 1970-01-01
      • 1970-01-01
      • 2013-03-21
      相关资源
      最近更新 更多