我对在目录中递归地 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
' exec
s 的钩子会覆盖目标目录中的文件。
尝试解决此问题:
$ 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