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

字符串的grep文件,并将目录复制到另一个目录,grep,cp,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/in

我有很多目录,每个目录中只有一个文件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要保留目录结构,请在传递模式下使用
cpio大约和以前一样古老,过去有更多的优势,但现在它有点陷入了困境。我对它不熟悉,主要是遵循一个古老的命令来建立这个命令:

mkdir dest_dir
cd source_dir
grep -Zlr "string" . |cpio -p0dmv ../dest_dir
这将通过管道将与您的条件匹配的*文件列表直接传递到
cpio
,该管道旨在以这种方式获取文件列表,然后进行存档或复制(“传递”
-p
)。我们在这里做后者,保留目录结构(
-d
)和修改时间(
-m
)。我已将其设置为详细(
-v
),以便您可以查看进度。如果您是通过ssh进行连接,您可能不希望这样做,因为通过网络呈现每个文件名可能会减慢进程

*关于空终止:我使用
grep-Zl
cpio-0
来解决包含换行符的文件名问题(不要这样做)
grep-Zl
列出由空字符(路径中唯一无效字符)分隔的所有匹配文件,
cpio-0
需要以空结尾的输入(正如
xargs-0
一样)

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

这将创建目标目录,进入源目录,并使用
-Zl
(以null结尾的文件列表*)和
-r
(递归)运行grep
xargs-0
将该列表转换为
tar
的参数,后者将其存档。另一个
tar
实例将它们提取到目标目录中


**
xargs
默认值为
--max procs=1
,并且应该一次运行一个进程,导致多个tarball连接在一起。tar格式应该能够处理这个问题,不过建议一个简单的解决方案是在提取的
tar
中添加
-i
()来解决这个问题。我将它添加到上面的代码中,但没有对其进行测试。

我假设您的第一个代码块有一个输入错误,其中
.htmk
应该是
.html
我预计对于给定的字符串,每个目录中最多有1,80000个目录,每个目录中有一个html文件。所以我希望这不会带来问题。18万。单个文件的目录总数为60万,根据每次运行一个文件的30个“字符串”将其分为30多个子目录。我希望
xargs
调用多个
tar
s会起作用。好的,我已经更新了我的答案,使用了
cpio
,它是为这类事情而构建的。效果很好。谢谢
mkdir dest_dir
cd source_dir
grep -Zlr "string" . |xargs -0 tar -pc |tar -pxi --directory=../dest_dir