如何复制在 OSX 上使用 grep 找到的文件

How to copy files found with grep on OSX

我想复制我在 OSX 系统上使用 grep 找到的文件,其中 cp 命令没有 -t 选项.

做这样的事情依赖于 cp 中的 -t 标志。但是,就像那张海报一样,我想获取从 grep 收到的文件列表,然后对其执行命令,例如:

grep -lr "foo" --include=*.txt * 2>/dev/null | xargs cp -t /path/to/targetdir

效率低于 cp -t,但这有效:

grep -lr "foo" --include=*.txt * 2>/dev/null |
  xargs -I{} cp "{}" /path/to/targetdir

解释:

对于 filenames | xargs cp -t destinationxargs 将传入的文件名更改为这种格式:

cp -t destination filename1 ... filenameN

即,它只运行 cp 一次(实际上,每几千个文件名运行一次——如果 shell 太长,xargs 会中断命令行).

对于 filenames | xargs -I{} cp "{}" destination,另一方面,xargs 将传入的文件名更改为这种格式:

cp "filename1" destination
...
cp "filenameN" destination

即,它为每个传入的文件名运行一次 cp,这要慢得多。对于大量(例如,>10k)非常小(例如,<10k)的文件,我猜它甚至可能慢数千倍。但它确实有效:)

PS:另一种流行的技术是使用 findexec 函数代替 xargs,例如