在此用例中,如何正确地使用 grep 和 cp 管道查找

在此用例中,如何正确地使用 grep 和 cp 管道查找

我对在目录中递归地 grep 查找某个模式的字符串,然后将匹配的文件复制到目标目录感兴趣。我以为我可以做类似下面的事情,但对于 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

我认为你不需要 find。递归 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

上述示例均未考虑到 生成重复结果(具有相同名称,但位于不同位置的文件)的可能性grep-l因此find' execs 的钩子会覆盖目标目录中的文件。

尝试解决此问题:

$ 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

相关内容