在此用例中如何使用 grep 和 cp 正確透過管道查找

在此用例中如何使用 grep 和 cp 正確透過管道查找

我感興趣的是遞歸地在目錄中查找字串以查找模式,然後將匹配文件 cp'ing 到目標目錄。我以為我可以做類似下面的事情,但是對於linux的find工具來說似乎沒有意義:

find . -type f -exec grep -ilR "MY PATTERN" | xargs cp /dest/dir

有更好的方法來解決這個問題嗎?或者一種可行的方法將是一個堅實的開始。

答案1

man xargs並觀察-I旗幟。

find . -type f -exec grep -ilR "MY PATTERN" {} \; | xargs -I % cp % /dest/dir/

另外,在標誌後面find需要一個\;或。+-exec

答案2

我認為你不需要找到。遞歸 grep:

grep -rl "MY PATTERN" .

答案3

xargs讀取其標準輸入並將它們放在要執行的命令的末尾。正如你所寫的,你最終會執行

cp /dest/dir sourcefile1 sourcefile2 sourcefile3

這與你想要的相反。

您可以使用該-I選項指定 的佔位符xargs,如下所示:xargs -I '{}' cp '{}' /dest/dir

另外,find還負責遞歸,所以你grep不需要-R.

最終解決方案:

find . -type f -exec grep -il "MY PATTERN" '{}' + | xargs -I '{}' cp '{}' /dest/dir

答案4

上面的範例都沒有考慮greps-l產生重複結果(具有相同名稱但位於不同位置的檔案)的可能性,因此findsexec的鉤子會覆蓋目標目錄中的檔案。

嘗試解決這個問題:

$ tree foo
foo
├── bar
│   ├── baz
│   │   └── file
│   └── file
├── destdir
└── file

3 directories, 3 files

$ while read a; do mv $a foo/destdir/$(basename $a).$RANDOM; done < <(grep -rl content foo)

$ tree foo
foo
├── bar
│   └── baz
└── destdir
    ├── file.10171
    ├── file.10842
    └── file.25404

3 directories, 3 files

相關內容