我想将数千个小文本文件合并成一个大文本文件。我将它们放在具有以下结构的目录中:timestamp1/status.txt. 例如:20130430133144/status.txt。到目前为止,我知道
cat */* > bigtextfile.txt
Run Code Online (Sandbox Code Playgroud)
适用于少量文件。但它适用于更高的数字吗?我想知道是否cat要收集所有文件的内容,然后尝试保存到bigtextfile. 否则,我想必须有另一种方法来做到这一点,比如获取一个文件,将其附加到bigtextfile,然后获取另一个等等。
Sté*_*las 10
在:
cat */* > bigtextfile.txt
Run Code Online (Sandbox Code Playgroud)
shell 将扩展*/*到(非隐藏)匹配文件的排序列表中,并将cat这些文件路径作为参数执行。
cat将依次打开每个文件并在其标准输出上写入从文件中读取的内容。cat一次不会在内存中保存一个以上的充满数据的缓冲区(比如几千字节)。
不过,您可能会遇到的一个问题是,to 的参数列表cat太大,以至于达到了execve()系统调用的参数大小的限制。因此,您可能需要拆分该文件列表并运行cat多次。
您可以使用xargs它(此处使用 GNU 或 BSDxargs用于非标准-r和-0选项):
printf '%s\0' */* | xargs -r0 cat -- > big-file.txt
Run Code Online (Sandbox Code Playgroud)
(因为printf是在 shell 中构建的,它不会通过execve系统调用,所以不会通过它的限制)。
或者find制作文件列表并根据需要运行尽可能多的 cat 命令:
find . -mindepth 2 -maxdepth 2 -type f -exec cat {} + > big-file.txt
Run Code Online (Sandbox Code Playgroud)
或者便携:
find . -path './*/*' -prune -type f -exec cat {} + > big-file.txt
Run Code Online (Sandbox Code Playgroud)
(注意,尽管与 相反*/*,它将包含隐藏文件(和隐藏目录中的文件),而不是在指向目录的符号链接中查找文件,并且不会对文件列表进行排序)。
如果在最新版本的 Linux 上,您可以通过执行以下操作来解除对参数大小的限制:
ulimit -s unlimited
cat -- */* > big-file.txt
Run Code Online (Sandbox Code Playgroud)
使用zsh,您还可以使用zargs:
autoload zargs
zargs -- */* -- cat > big-file.txt
Run Code Online (Sandbox Code Playgroud)
使用ksh93,您可以使用command -x:
command -x cat -- */* > big-file.txt
Run Code Online (Sandbox Code Playgroud)
所有这些都做同样的事情,拆分文件列表并cat根据需要运行尽可能多的命令。
随着ksh93再次,让您可以在execve()使用内置限制cat命令:
command /opt/ast/bin/cat -- */* > big-file.txt
Run Code Online (Sandbox Code Playgroud)
Nocat在开始写出之前不会缓冲所有文件。
但是,如果您有大量文件,则可能会遇到传递给cat. 默认情况下,Linux 内核只允许将固定数量的参数传递给任何程序(我不记得如何获取该值,但在大多数情况下是几千个)。
要解决此问题,您可以执行以下操作:
find -mindepth 2 -maxdepth 2 -type f -exec cat {} \; > bigtextfile.txt
Run Code Online (Sandbox Code Playgroud)
这基本上会cat分别调用find.
| 归档时间: |
|
| 查看次数: |
2523 次 |
| 最近记录: |