用于字符串的 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】:
要保留目录结构,请在传递模式下使用cpio
。 cpio
和 tar
差不多老了,以前有更多的优势,但它有点滑到了 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 -Zl
和cpio -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
调用多个tar
s 会起作用。好的,我已经更新了我的答案以使用 cpio
,它是为这类事情而构建的。
工作正常。谢谢。以上是关于用于字符串的 grep 文件并将目录复制到另一个目录的主要内容,如果未能解决你的问题,请参考以下文章
如何 grep 字符串的目录,将其重写为其他内容并保存在 bash 中? [复制]
编写一个程序将d:java目录下的所有.java文件复制到d:jad目录下,并将原来文件的扩展名从.java改为.jad
编写一个程序将d:java目录下的所有.java文件复制到d:jad目录下,并将原来文件的扩展名从.java改为.jad