在这个用例中如何正确地用grep和cp来查找pipe道

我感兴趣的是在一个模式的目录中recursion地刷新一个string,然后把匹配的文件复制到目标目录。 我以为我可以做类似下面的事情,但是对于linux的查找工具似乎没有意义:

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

有没有更好的方法去做这件事? 或者甚至是一种方法,将是一个坚实的开始。

man xargs ,看看-I旗帜。

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

另外, find一个\; 或者在-exec标志后加上+

我不认为你需要find。 recursiongrep:

 grep -rl "MY PATTERN" . 

xargs读取它的标准input并将它们放在要执行的命令的末尾。 正如你写的那样,你最终会执行

 cp /dest/dir sourcefile1 sourcefile2 sourcefile3 

这是从你想要的东西倒退。

您可以使用-I选项为xargs指定一个占位符,如下所示: xargs -I '{}' cp '{}' /dest/dir

此外, find照顾的recursion,所以你的grep不需要-R

最终解决scheme

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

上面的例子都没有考虑grep-l生成重复结果的可能性(同名的文件,但在不同的地方),因此find exec的钩子覆盖目标目录中的文件。

试图解决这个问题:

 $ 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