我有一个文件集合( *.zip、*.txt、*.tar.gz、*.doc、...等)。这些文件驻留在路径中。我想找到所有文件(*.txt),然后仅复制包含特定单词的文本文件(例如LINUX/UNIX)。
我运行了以下命令:
find . -name "*.txt" | grep 'LINUX/UNIX'
该命令能够找到所有文本文件,然后“grep”通过仅列出包含“LINUX/UNIX”的文本文件来过滤结果文本文件。
如何将这些最终文件(即包含“LINUX/UNIX”的文本文件)复制到所选的特定路径?
我尝试申请xargs
find . -name "*.txt" | grep 'LINUX/UNIX' | xargs cp <to a path>
但没有成功
答案1
尝试:
grep -rl --null --include '*.txt' LINUX/UNIX . | xargs -0r cp -t /path/to/dest
由于此命令使用 NUL 分隔,因此对于所有文件名都是安全的,包括那些名称复杂、包含空格、制表符甚至换行符的文件名。
以上需要 GNU cp
。对于 MacOS/FreeBSD,请尝试:
grep -rl --null --include '*.txt' LINUX/UNIX . | xargs -0 sh -c 'cp "$@" /path/to/dest' sh
怎么运行的:
grep
选项和参数-r
告诉 grep 在目录结构中递归搜索。 (在 FreeBSD 上,-r
将跟随符号链接进入目录。对于 OS/X 或最新版本的 GNU 来说,情况并非如此grep
。)--include '*.txt'
告诉 grep 只返回名称与 glob 匹配的文件*.txt
(包括隐藏的文件,如.foo.txt
或.txt
)。-l
告诉 grep 仅返回匹配文件的名称,而不返回匹配本身。--null
告诉 grep 使用 NUL 字符来分隔文件名。 (由下--null
支持grep
GNU/Linux,苹果系统和自由BSD但不是 开放BSD.)LINUX/UNIX
告诉 grep 仅查找内容包含正则表达式的文件LINUX/UNIX
.
在当前目录中搜索。您可以在最新版本的 GNU 中省略它grep
,但是您需要传递一个--
选项终止符来cp
防止以-
.
xargs
选项和参数-0
告诉 xargs 期待 NUL 分隔的输入。-r
告诉 xargs 除非找到至少一个文件,否则不要运行该命令。 (此选项在 BSD 或 OSX 上都不需要,并且与 OSX 不兼容xargs
。)cp -t /path/to/dest
将目录复制到目标目录。 (-t
需要 GNUcp
。)
答案2
更便携(仅限 POSIX 功能):
find . -type f -name '*.txt' -exec grep -q LINUX/UNIX {} \; -exec cp {} /path/to/dest \;
答案3
以下 sh/Bash oneliner 是另一种方法,但仅适用于当前目录,并且不会递归:
for f in ./*.txt; do if grep -l 'LINUX/UNIX' "$f"; then cp "$f" /path/to/dest/; fi; done
grep选项-l
将打印正在复制的文件列表,但-q
如果您不想在屏幕上看到任何内容,则可以使用该选项。
答案4
我不确定为什么原始字符串不起作用。以下命令对我有用。
查找 / -name (文件名*) | grep '(文件名.扩展名)'| xargs cp -t ./
就我而言, filename* 是具有相同名称和不同文件类型(txt、zip 等)的文件的集合。我执行 grep 仅查找 filename.txt 并将其复制到我的目标目录(当前为 ./)。