我在每个目录中只有一个文件 - 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
答案 0 :(得分:2)
要保留目录结构,请在直通模式下使用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建议一个简单的解决方案是在解压缩问题-i
中添加tar
(ignore zeros}来解决这个问题。我将它添加到上面的代码中但没有测试过。