grep -r(递归),删除/隐藏所有目录

grep -r(递归),删除/隐藏所有目录

菜鸟在这里 - 我想跑grep -r asdf菜鸟在这里 -但我只想在我的目录中进行唯一的匹配(即忽略任何目录,仅显示唯一匹配项)。

于是我就跑了grep -r asdf | sort --unique。但是 - 这不起作用,因为目录名称不同(dir1/a.txt asdfdir2/a.txt asdf)。

我没有看到grep -riol排除目录的选项(我尝试过例如),我想这对于函数的范围几乎没有意义。我可以以某种方式切掉目录并只显示匹配的文件名+匹配(可能没有心灵/宇宙弯曲正则表达式/sed/...)?

答案1

我认为使用默认功能grep无法做到这一点。

你可以使用这样的东西,这只是一个“小”正则表达式:

grep -r asdf | sed '#^.*/##' | sort --unique

注意:如果搜索模式包含/

答案2

尝试这个,

grep -r abcd | awk -F ':' '{gsub(/.*\//,"",$1) }1' | awk '!seen[$1]++'
  • gsub将删除目录结构。 (/.*\//,"",$1)将删除第一个字段 ($1) 中最后一个匹配 '/' 之前的所有 (.*)。
  • !seen[$1]++将唯一化文件名。

:注意:目录名中不能有。

答案3

这按基本名称和 grep 输出进行分组:

   ]# grep -ro '#include' include/ |sed -E 's|.*/(.*:)|\1|' |uniq -c |sort|tail -n7
         28 kvm_host.h:#include
         28 mm.h:#include
         29 ib_verbs.h:#include
         31 net_namespace.h:#include
         32 sock.h:#include
         44 fs.h:#include
         48 drmP.h:#include

我曾经grep -o得到过一些重复的东西。同时它省略了斜杠......

如果名称包含:sed 将无法正常工作。正则表达式首先丢弃直到最后的所有内容/,然后存储所有内容直到:as \1

我使用是-E因为(子表达式)和|斜杠。


子表达式(.*:)有点简单(如果 grep 行包含冒号,则会失败)。如果省略冒号,则当该行包含斜杠时,它将失败。


看着这个输出我说这是不可能的理论上(以这种方式解析 grep 的输出):

]# grep -r "" d*
d:/ir:/afile...in file "d"
d:/ir:/afile...in file "ir"

这是相同的。我需要一个末尾带有冒号的目录和一个名称和内容重叠的文件。

]# ls d* 
d

'd:':
ir

grep --color与众不同!


include目录是来自 Linux 内核源代码的目录。一个包含文件中的一整行如下所示。

]# grep -rH '#incl' include/linux/aio.h 
include/linux/aio.h:#include <linux/aio_abi.h>

答案4

通过 的输出grep --null,以下 GNUawk程序应适用于任何文件名:

BEGIN {
    # OFS will be printed between
    # each filename and matched line
        OFS = ":"

    # Use null-byte as a record separator
    # to use with output from grep --null
        RS = "\0"

    # Apart from the first record,
    # everything up to the first newline
    # of a record is the matched line from grep
    # Everything after first newline is a filename
        FPAT = "^[^\n]*|\n.*$"

}
NR == 1 {
    # Entire first record
    # is the first filename
    # set `file` to the basename
        file = gensub(".*/","",1)
        next
}
! seen[file, $1]++ {
    # If filename+match
    # not seen, print it
        print file, $1
}
{
    # Get basename of file
    # from next match
        file = gensub(".*/","",1,$2)
}

grep --null -rF asdf . | awk -f see_above.gawk

相关内容