用于字符串的 grep 文件并将目录复制到另一个目录

Posted

技术标签:

【中文标题】用于字符串的 grep 文件并将目录复制到另一个目录【英文标题】:grep file for string and copy directory to another directory 【发布时间】:2016-07-06 17:23:40 【问题描述】:

我有大量目录,每个目录中只有一个文件 -- 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

【问题讨论】:

我假设你的第一个代码块有错字,.htmk 应该是 .html 【参考方案1】:

要保留目录结构,请在传递模式下使用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 建议一个简单的解决方案是在提取的tar 中添加一个-i (ignore zeros) 来解决这个问题。我在上面的代码中添加了它,但没有测试过。

【讨论】:

对于给定的字符串,我预计最多有 1,80,000 个目录,每个目录中只有一个 html 文件。所以我希望这不会产生问题。 1,80,000。具有单个文件的总目录为 60 万个,根据一次运行一个的 30 个“字符串”将分类为 30 个奇数子。 我试过并得到这个错误:xargs:tar:由信号13终止 坚果。我希望xargs 调用多个tars 会起作用。好的,我已经更新了我的答案以使用 cpio,它是为这类事情而构建的。 工作正常。谢谢。

以上是关于用于字符串的 grep 文件并将目录复制到另一个目录的主要内容,如果未能解决你的问题,请参考以下文章

如何 grep 字符串的目录,将其重写为其他内容并保存在 bash 中? [复制]

编写一个程序将d:java目录下的所有.java文件复制到d:jad目录下,并将原来文件的扩展名从.java改为.jad

编写一个程序将d:java目录下的所有.java文件复制到d:jad目录下,并将原来文件的扩展名从.java改为.jad

linux怎么将一个文件移动到另一个目录下

将多个pdf文件复制到另一个目录,并将每个文件创建文件夹及其名称

使用python:查找文件并复制到另一个目录