问题描述
我有大量目录,每个目录中只有一个文件 -- index.html --.我想使用 grep 在文件中查找模式,然后将目录与文件一起复制到另一个目录.
复制文件的示例,我已经看到了,但我想将包含文件的目录复制到另一个目录中.
所以说以下是使用
与目录匹配的文件列表grep -rl "string" source_dird1/index.htmkd2/index.htmld3/index.html
......一长串.
现在想要复制到 dest-dir,所以 dest_dir 看起来像
(递归).xargs -0
将该列表转换为 tar
的参数,后者将它们存档.另一个 tar
实例然后将它们提取到目标目录中.** xargs
默认为 --max-procs=1
并且应该一次运行一个进程,从而产生多个 tarball串联在一起.tar 格式应该能够处理这个问题,尽管 进一步阅读 建议一个简单的解决方案是添加 -i
(忽略零) 到提取 tar
来解决这个问题.我把它添加到上面的代码中,但没有测试过.
I have large number of directories with just one file -- index.html -- in each directory. I would want to use grep to look for pattern in file and then copy the directory along with the file to another directory.
Example for copying files, I have seen, but I would want to copy the directory with the file in to another directory.
so say following are the list of matching files with directory using
grep -rl "string" source_dir
d1/index.htmk
d2/index.html
d3/index.html
......a long list.
Now would want to copy to dest-dir so dest_dir looks like
.
..
d1/index.html
d2/index.html
d3/index.html
...
...
TIA
To preserve the directory structure, use cpio
in pass-through mode. cpio
is about as old as tar
and used to have more advantages, but it has kind of slipped into obscurity. I'm new to it and mostly followed an ancient Linux Journal cpio guide to build this command:
mkdir dest_dir
cd source_dir
grep -Zlr "string" . |cpio -p0dmv ../dest_dir
This passes a null-terminated* list of files matching your criteria through a pipeline directly into cpio
, which is designed to take a list of files in this manner and then either archive or copy ("pass-through," -p
). We do the latter here, preserving the directory structure (-d
) as well as modification times (-m
). I've set this to verbose (-v
) so you can watch the progress. If you're connecting via ssh
, you might not want that since rendering each filename over the network can slow down the process.
* Regarding null termination: I used grep -Zl
with cpio -0
to work around the issue of file names containing newlines (don't do that!); grep -Zl
lists all matching files delimited by null characters (the only invalid character for a path) and cpio -0
expects null-terminated inputs (as does xargs -0
).
I originally recommended tar
to create a temporary archive and tar
again to extract it into the new location. This used xargs
to convert the file list into arguments since tar
doesn't have the ability to accept its list of files within another file (or standard input, as cpio
does), but xargs
splits commands that are too long into multiple calls and tar
can't extract the concatenated output**.
mkdir dest_dir
cd source_dir
grep -Zlr "string" . |xargs -0 tar -pc |tar -pxi --directory=../dest_dir
This makes your destination directory, enters the source directory, and runs grep with -Zl
(null-terminated file list*) and -r
(recursive). xargs -0
turns that list into arguments for tar
, which archives them. Another tar
instance then extracts them into the destination directory.
** xargs
defaults to --max-procs=1
and should run one process at a time, resulting in multiple tarballs that are concatenated together. The tar format is supposed to be able to handle this, though further reading suggested a simple solution is to add a -i
(ignore zeros) to the extracting tar
to solve that problem. I added it to the above code but have not tested it.
这篇关于字符串的grep文件并将目录复制到另一个目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!