将大量文件合并到一个目录中

将大量文件合并到一个目录中

我在一个目录中有大量文件,目前有 10,804 个文件。文件数量可以在 5 到 100,000 之间浮动。

我正在寻找一种方法,将每 250 个单独的文件合并为一个大文件,其余文件合并为一个小文件。例如 1200 个文件,我想要 4 个 250 个文件和 1 个 200 个文件

我正在使用 bash shell。

答案1

您可以编写一个简单的循环来使用数组来执行此操作,并且${x:s:l}参数扩展:

files=(*)
for (( i = 0; i < ${#files[@]}; i += 250 ))
do
    cat -- "${files[@]:$i:250}" > "file$i.combined"
done

在这里,我们将所有(非隐藏)文件收集.到一个数组中files(文件名按词法排序),并从 0 循环计数到 250 秒内有多少个文件。对于每个 250,我们将文件名(0-249、250-499 等)展开为参数,并将cat输出放入file0.combinedfile250.combined等中。

这只是传统 C 风格for循环的 Bash 版本。因为无论如何你都必须为每个单独的循环循环cat,所以没有太多必要让事情变得过于复杂。

.combined最后您将得到几个文件 - 因为文件名已经扩展,这些文件将不会再次包含在串联中,但如果您第二次运行该命令,它们就会包含在串联中。如果这是一个问题,您可以将它们放在其他地方,然后删除它们,或者如果它直接发送到打印机,甚至只是通过管道传输到lp.

答案2

简单地:

#!/bin/bash
files_count=`ls -1 ./ | wc -l`
block_size=10
blocks_count=$(($files_count/$block_size))

for i in $(seq 1 1 $blocks_count); do
    files=`find . -type f -exec readlink -f {} \; | head -$block_size`
    for j in $files; do
        if [ -f $j ] && [[ "$j" != outfile* ]] ; then
            cat $j >> outfile$i
    fi
    done
done
# remainder part
for i in *; do
    if [ -f $i ] && [[ "$i" != outfile* ]] ; then
        cat $i >> outfilelast
    fi
done

笔记:

您的文件按字母顺序合并,脚本也应放置在同一目录中。

答案3

我尝试用下面的方法

for ((i=1;i<=1200;i++)); do j=$(($i + 249 )); sed -n ''$i','$j'p' filename >individual_$i ;i=$j; done

答案4

假设您可以按照find找到它们的顺序组合它们:

find . -maxdepth 1 -type f -print0 |
xargs -0 -L 250 sh -c 'cat "$@" >/tmp/combined-${1##*/}' sh

file-1对于包含名称最多为file-739(作为示例)的文件的目录,这将创建/tmp名为combined-file-1combined-file-251和 的文件combined-file-501,其中后面的位combined-是该组合文件中第一个文件的名称。

cat它通过调用重复执行的内联 shell 脚本来批量连接文件,一次最多连接 250 个文件xargs${1##*/}该脚本中的 会从当前批处理的第一个文件的路径名中删除任何目录路径)来实现此目的。该xargs实用程序从 中获取以 null 结尾的字符串形式的文件名find。该find实用程序将(仅)查找当前目录并输出其中与常规文件相对应的所有路径名。

然后您将打印这些/tmp/combined-*文件。

要仅处理具有特定后缀的文件,例如.txt,请-name '*.txt'find命令中使用 before -print0

-print0通常执行的操作和find选项-0xargs非标准的。

相关内容