字符串和副本目录的grep文件到另一个目录

时间:2016-07-06 17:23:41

标签: grep cp

我在每个目录中只有一个文件 - index.html - 有大量目录。我想使用grep在文件中查找模式,然后将目录与文件一起复制到另一个目录。

我已经看到了复制文件的示例,但我想将带有该文件的目录复制到另一个目录中。

以下是使用

的目录匹配文件列表
grep -rl "string" source_dir


d1/index.htmk
d2/index.html
d3/index.html

... ... 很长的名单。

现在想要复制到dest-dir,所以dest_dir看起来像

.
..
d1/index.html
d2/index.html
d3/index.html
...
...

TIA

1 个答案:

答案 0 :(得分:2)

要保留目录结构,请在直通模式下使用cpiocpiotar差不多,曾经有过更多优势,但它有点落入obscurity。我是新手,大部分都遵循古老的Linux Journal cpio guide来构建这个命令:

mkdir dest_dir
cd source_dir
grep -Zlr "string" . |cpio -p0dmv ../dest_dir

这会将符合条件的null-terminated * 文件列表通过管道直接传递到cpio,该文件旨在以这种方式获取文件列表,然后存档或复制(“传递”,-p)。我们在这里做后者,保留目录结构(-d)以及修改时间(-m)。我将其设置为详细(-v),以便您可以观察进度。如果您通过ssh进行连接,则可能不希望这样,因为通过网络呈现每个文件名可能会降低该过程的速度。

* 关于空终止:我使用grep -Zlcpio -0来解决包含换行符的文件名问题(不要那样做!) ; grep -Zl列出由空字符分隔的所有匹配文件(路径的唯一无效字符),cpio -0期望以空值终止的输入(xargs -0也是如此)。

我最初建议tar创建临时存档,再次tar将其解压缩到新位置。这使用xargs将文件列表转换为参数,因为tar无法接受其他文件中的文件列表(或标准输入,如cpio那样),但是xargs将过长的命令拆分为多个调用,而tar无法提取连接的输出 **

mkdir dest_dir
cd source_dir
grep -Zlr "string" . |xargs -0 tar -pc |tar -pxi --directory=../dest_dir

这将生成目标目录,进入源目录,并使用-Zl(以空值终止的文件列表 * )和-r(递归)运行grep。 xargs -0将该列表转换为tar的参数,并将其归档。然后,另一个tar实例将它们提取到目标目录中。

** xargs默认为--max-procs=1,并且应该一次运行一个进程,从而导致多个tarball连接在一起。 tar格式应该能够处理这个问题,尽管further reading建议一个简单的解决方案是在解压缩问题-i中添加tarignore zeros}来解决这个问题。我将它添加到上面的代码中但没有测试过。