如何使用Unix find execute和cat将子目录中的文件连接到单个文件中?
我可以这样做:如何使用Unix find execute和cat将子目录中的文件连接到单个文件中?,unix,command-line,Unix,Command Line,我可以这样做: $ find . . ./b ./b/foo ./c ./c/foo setopt extendedglob 这是: $ find . -type f -exec cat {} \; This is in b. This is in c. 但不是这个: $ find . -type f -exec cat > out.txt {} \; 为什么不呢?find的-exec参数为它找到的每个文件运行一次指定的命令。尝试: $ find . -type f -exec c
$ find .
.
./b
./b/foo
./c
./c/foo
setopt extendedglob
这是:
$ find . -type f -exec cat {} \;
This is in b.
This is in c.
但不是这个:
$ find . -type f -exec cat > out.txt {} \;
为什么不呢?find的-exec参数为它找到的每个文件运行一次指定的命令。尝试:
$ find . -type f -exec cat {} \; > out.txt
或:
xargs将其标准输入转换为指定命令的命令行参数。如果您担心文件名中嵌入空格,请尝试:
$ find . -type f -print0 | xargs -0 cat > out.txt
将find的输出重定向到一个文件中如何,因为您只需要将所有文件合并到一个大文件中:
find . -type f -exec cat {} \; > /tmp/out.txt
你可以这样做:
$ cat `find . -type f` > out.txt
或者,如果您使用真正优秀的Z shell(
zsh
),则只需省去无用的查找,您可以这样做:
$ find .
.
./b
./b/foo
./c
./c/foo
setopt extendedglob
(这应该在您的.zshrc
中)
然后:
刚刚好用:-)嗯。。。当您将out.txt输出到当前目录时,find似乎正在递归 试试像这样的东西
find . -type f -exec cat {} \; > ../out.txt
也许您已经从其他响应中推断出,
符号在find将其作为参数获取之前由shell进行解释。但要回答您的“为什么不”,让我们看看您的命令,它是:
$ find . -type f -exec cat > out.txt {} \;
因此,您将给出find
这些参数:“-键入“f”-exec”“cat”
您将给出重定向这些参数:“out.txt”{}“
和;”
。这会混淆find
,因为没有用分号终止-exec
参数,也没有使用文件名作为参数(“{}”),这也可能混淆重定向
看看其他建议,您应该真正避免在找到的同一目录中创建输出。但他们会考虑到这一点。而且-print0 | xargs-0
组合非常有用。您想要键入的内容可能更像:
$ find . -type f -exec cat \{} \; > /tmp/out.txt
现在,如果您真的只有一级子目录和普通文件,您可以做一些愚蠢而简单的事情,如:
cat `ls -p|sed 's/\/$/\/*/'` > /tmp/out.txt
它获取ls
以列出将'/'
附加到目录的所有文件和目录,而sed
将向目录附加一个'*'
。然后shell将解释此列表并展开globs。假设这不会导致shell处理太多文件,这些文件都将作为参数传递给cat,输出将写入out.txt。尝试以下操作:
(find . -type f -exec cat {} \;) > out.txt
在bash中你可以做到
cat $(find . -type f) > out.txt
使用$()可以从命令中获取输出并将其传递给另一个我在Darwin上,因此这可能是一个应该发布的警告,但使用其中一些方法,我得到了一个循环行为,其中文件的内容被无限期地连续追加。是的,这是因为out.txt与文件位于同一目录中;把out.txt放在.yes之外的某个地方。这就是诀窍。输出文件不能与您在中找到的目录相同。您在标题中拼错了“concatenate”。将输出文件写入同一目录显然是个问题。如果您避免这样做,许多解决方案都会起作用。如果您将此更改为将输出文件写入与您正在查找的目录不同的目录,则会起作用。只要find没有找到太多的文件,这种方法就会起作用。使用xargs进行补偿。