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

相關內容