簡體   English   中英

我如何遞歸grep所有目錄和子目錄?

[英]How do I recursively grep all directories and subdirectories?

我如何遞歸grep所有目錄和子目錄?

find . | xargs grep "texthere" *
grep -r "texthere" .

第一個參數表示要搜索的正則表達式,而第二個參數表示應該搜索的目錄。 在這種情況下, . 表示當前目錄。

注意:這適用於 GNU grep,並且在某些平台(如 Solaris)上,您必須專門使用 GNU grep,而不是傳統實現。 對於 Solaris,這是ggrep命令。

如果您知道所需文件的擴展名或模式,另一種方法是使用--include選項:

grep -r --include "*.txt" texthere .

您還可以使用--exclude提及要排除的文件。

如果您經常搜索代碼, Ag(The Silver Searcher)是 grep 的更快替代品,它是為搜索代碼而定制的。 例如,默認情況下它是遞歸的,並自動忽略.gitignore列出的文件和目錄,因此您不必繼續將相同的繁瑣排除選項傳遞給 grep 或 find。

還有:

find ./ -type f -print0 | xargs -0 grep "foo"

grep -r是一個更好的答案。

我現在總是使用(即使在帶有GoW 的Windows 上- Windows 上的Gnu ):

grep --include="*.xxx" -nRHI "my Text to grep" *

(正如kronen評論中所指出的,您可以添加2>/dev/null以取消權限被拒絕的輸出)

這包括以下選項:

--include=PATTERN

在目錄中遞歸只搜索匹配PATTERN文件。

-n, --line-number

使用輸入文件中的行號為每一行輸出添加前綴。

(注意: phuclv 在注釋中添加-n大大降低性能,因此您可能希望跳過該選項)

-R, -r, --recursive

遞歸讀取每個目錄下的所有文件; 這等效於-d recurse選項。

-H, --with-filename

打印每個匹配項的文件名。

-I     

處理一個二進制文件,就好像它不包含匹配的數據一樣;
這等效於--binary-files=without-match選項。

如果我想要不區分大小寫的結果,我可以添加 ' i ' ( -nRHIi )。

我可以得到:

/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43:            'git.hidden'      => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21:            $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32:        $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20:    protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170:     * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176:        return $this->hidden;
...

在 POSIX 系統中,您找不到用於grepgrep -rn "stuff" . -r參數grep -rn "stuff" . 不會運行,但如果您使用find命令,它將:

find . -type f -exec grep -n "stuff" {} \\; -print

SolarisHP-UX同意。

通配**

使用grep -r有效,但它可能會矯枉過正,尤其是在大文件夾中。

對於更實際的用法,這里是使用globbing 語法( ** ) 的語法

grep "texthere" **/*.txt

僅使用模式選擇模式搜索特定文件。 它適用於受支持的 shell,例如Bash +4zsh

要激活此功能,請運行: shopt -s globstar

另請參閱:如何在 Linux 上查找包含特定文本的所有文件?

git grep

對於 Git 版本控制下的項目,請使用:

git grep "pattern"

這要快得多。

ripgrep

對於較大的項目,最快的ripgrep工具是ripgrep ,默認情況下它會遞歸 grep 文件:

rg "pattern" .

它建立在Rust 的正則表達式引擎之上,該引擎使用有限自動機、SIMD 和積極的文字優化來使搜索速度非常快。 檢查這里詳細分析

只是文件名也很有用

grep -r -l "foo" .

要查找path遞歸包含特定stringfiles名稱,請使用以下UNIX命令:

find . | xargs grep "searched-string"

對於Linux

grep -r "searched-string" .

UNIX服務器上查找文件

find . -type f -name file_name

在 LINUX 服務器上查找文件

find . -name file_name

如果您只想關注實際目錄,而不是符號鏈接,

grep -r "thingToBeFound" directory

如果你想跟隨符號鏈接以及實際目錄(注意無限遞歸),

grep -R "thing to be found" directory

由於您嘗試遞歸 grep,以下選項也可能對您有用:

-H: outputs the filename with the line

-n: outputs the line number in the file

因此,如果您想在當前目錄或任何子目錄中查找包含 Darth Vader 的所有文件並捕獲文件名和行號,但不希望遞歸遵循符號鏈接,則命令為

grep -rnH "Darth Vader" .

如果您想在目錄中查找所有提及的單詞 cat

/home/adam/Desktop/TomAndJerry 

並且您當前在目錄中

/home/adam/Desktop/WorldDominationPlot

並且您想要捕獲文件名而不是字符串“cats”的任何實例的行號,並且您希望遞歸跟隨符號鏈接(如果找到它們),您可以運行以下任一

grep -RH "cats" ../TomAndJerry                   #relative directory

grep -RH "cats" /home/adam/Desktop/TomAndJerry   #absolute directory

來源:

運行“grep --help”

符號鏈接的簡短介紹,適用於閱讀此答案並因我對它們的引用而感到困惑的任何人: https : //www.nixtutor.com/freebsd/understanding-symbolic-links/

ag 是我現在最喜歡的方式github.com/ggreer/the_silver_searcher 它與 ack 基本相同,但還有一些優化。

這是一個簡短的基准。 我在每次測試之前清除緩存(參見https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache

ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .

real    0m9.458s
user    0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .

real    0m6.296s
user    0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .

real    0m5.641s
user    0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache

real    0m0.154s
user    0m0.224s
sys 0m0.172s

這應該有效:

grep -R "texthere" *

如果您正在從目錄結構中find所有文件中的特定內容,您可以使用find因為它更清楚您在做什么:

find -type f -exec grep -l "texthere" {} +

請注意, -l (L 的小寫)顯示包含文本的文件的名稱。 如果您想打印匹配本身,請將其刪除。 或者使用-H將文件與匹配項放在一起。 總之,其他選擇是:

find -type f -exec grep -Hn "texthere" {} +

其中-n打印行號。

這是在我當前的機器上適用於我的情況的一個(Windows 7 上的 git bash):

find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"

對於帶空格的路徑,我總是忘記 -print0 和 -0。

編輯:我的首選工具現在是 ripgrep: https : //github.com/BurntSushi/ripgrep/releases 它真的很快並且有更好的默認值(比如默認的遞歸)。 與我的原始答案相同的示例,但使用 ripgrep: rg -g "*.cs" "content pattern"

grep -r "texthere" . (通知期在最后)

(^ 信用: https : //stackoverflow.com/a/1987928/1438029


澄清:

grep -r "texthere" / (遞歸地grep所有目錄和子目錄)

grep -r "texthere" . (遞歸地grep這些目錄和子目錄)

grep 遞歸

grep [options] PATTERN [FILE...]

[選項]

-R, -r, --recursive

遞歸讀取每個目錄下的所有文件。

這等效於-d recurse--directories=recurse選項。

http://linuxcommand.org/man_pages/grep1.html

幫助

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive

替代品

ackhttp://beyondgrep.com/

ag ( http://github.com/ggreer/the_silver_searcher )

在 2018 年,您希望使用ripgrepthe-silver-searcher因為它們比替代方案快得多。

這是一個包含 336 個一級子目錄的目錄:

% find . -maxdepth 1 -type d | wc -l
     336

% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py'  1.24s user 2.23s system 283% cpu 1.222 total

% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$'  2.71s user 1.55s system 116% cpu 3.651 total

% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py'  1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs  6.65s user 0.49s system 32% cpu 22.164 total

在 OSX 上,這會安裝ripgrepbrew install ripgrep 這將安裝silver-searcherbrew install the_silver_searcher

把我的兩分錢扔在這里。 正如其他人已經提到的那樣grep -r不適用於每個平台。 這可能聽起來很傻,但我總是使用 git。

git grep "texthere"

即使目錄沒有暫存,我也只是暫存並使用 git grep。

在我的 IBM AIX 服務器(操作系統版本:AIX 5.2)中,使用:

find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \; 

這將打印出文件中的路徑/文件名和相對行號,例如:

./inc/xxxx_x.h

2865:/** 描述:stringYouWannaFind */

無論如何,它對我有用:)

下面是在UnixLinux環境下遞歸搜索String的命令。

對於UNIX命令是:

find . -name "string to be searched" -exec grep "text" "{}" \;

對於Linux命令是:

grep -r "string to be searched" .

有關可用標志的列表:

grep --help 

返回當前目錄中正則表達式texthere 的所有匹配項,以及相應的行號:

grep -rn "texthere" .

返回texthere 的所有匹配,從根目錄開始,具有相應的行號並忽略大小寫:

grep -rni "texthere" /

這里使用的標志:

  • -r遞歸
  • -n打印行號和輸出
  • -i忽略大小寫

請注意, find . -type f | xargs grep whatever find . -type f | xargs grep whatever find . -type f | xargs grep whatever當 find 匹配的文件太多時, find . -type f | xargs grep whatever類型的解決方案都會遇到“參數列表太長”錯誤。

最好的選擇是grep -r但如果它不可用,請使用find . -type f -exec grep -H whatever {} \\; find . -type f -exec grep -H whatever {} \\; 相反。

我想這就是你想要寫的

grep myText $(find .)

如果您想找到 grep 命中的文件,這可能還有其他幫助

grep myText $(find .) | cut -d : -f 1 | sort | uniq

只是為了好玩,如果@christangrant 的答案太多而無法輸入,請快速搜索 *.txt 文件:-)

grep -r texthere .|grep .txt

這是一個遞歸(用 bash 和 sh 輕輕測試)函數,它遍歷給定文件夾 ($1) 的所有子文件夾,並使用grep搜索給定文件 ($2) 中的給定字符串 ($3):

$ cat script.sh
#!/bin/sh

cd "$1"

loop () {
    for i in *
    do
        if [ -d "$i" ]
        then
            # echo entering "$i"
            cd "$i"
            loop "$1" "$2"
        fi
    done

    if [ -f "$1" ]
    then
        grep -l "$2" "$PWD/$1"
    fi

    cd ..
}

loop "$2" "$3"

運行它和一個示例輸出:

$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename

對於 .gz 文件,遞歸掃描所有文件和目錄更改文件類型或放置 *

find . -name \*.gz -print0 | xargs -0 zgrep "STRING"

在 Linux 系統上的所有文件中遞歸地 grep 字符串的另一種語法

grep -irn "string" /

顯示大量結果,因此您可能需要通過管道過濾輸出

The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM