如何将目录中的文本文件块合并到一个或多个文件?

如何将目录中的文本文件块合并到一个或多个文件?

我需要将目录中的文本文件块合并到一个或多个文件,然后压缩合并的文件。

例如:如果我在一个目录中有 50 万个文本文件,比如 A。我想将 50,000 个文件集合并为 1 个文件集,即我将有 10 个合并文件,每个文件包含 50,000 个文件的内容。最后,我想压缩每个合并的文件,即在此过程结束时总共会有 10 个 zip 文件。

我尝试在 shell 脚本中执行此操作。我无法找到解决方案。

有人可以让我知道使用 shell 脚本实现此目的的最有效方法吗?

答案1

正如我所看到的,您只有一个目录,其中包含大量文件,因此您需要将文件列表拆分为小文件集,而不是将它们连接起来,然后进行压缩,并在必要时删除小文件。

我只能建议以下方式:

cd /to/dir/with/many/files/
mkdir ../tmp
find . | split -l 50000 ../tmp/x
for i in ../tmp/x* ; do 
    while read filename ; do
        cat "$filename" >> "${i}.text" ;
        # rm "$filename" # uncomment it only if you need to delete small files
    done <"$i"
    zip "${i}.zip"  "${i}.text"
    # rm "${i}.text" # uncomment it only if you need to delete result file
done

答案2

这里有两种解决方案,一种是n将文件添加到单个存档中,另一种是首先将所有文件连接起来,然后进行压缩。

这两种方法的共同步骤是:

# Generate a list of files to be zipped
find . -type f > filelist

# Loop to process n files stepwise
n=50000
fileno=1

for i in $(seq 1 $n $(wc -l < filelist)); do
  # compression code goes here, see below
done

单独压缩文件

# automatic name generation
zipfile=$(printf "%04d" $((fileno++)))

# extract lines $i to $i+$n-1 from filelist 
sed -n "$i,$((i+n-1))p" filelist | zip $zipfile -@

连接和压缩

如果您想使用gzip(和其他压缩器)来做到这一点,那将非常简单:

zipfile=$(printf "%04d" $((fileno++)))
sed -n "$i,$((i+n-1))p" filelist | xargs cat | gzip > $zipfile.gz

由于zip不支持这种模式(至少不支持我所拥有的模式),因此您需要一种不同的方法。zip支持命名管道 ( -FI),其中存档内的文件获取命名管道的名称,因此在循环内执行类似的操作应该有效:

zipfile=$(printf "%04d" $((fileno++)))
mkfifo $zipfile
zip -FI $zipfile $zipfile &
sed -n "$i,$((i+n-1))p" filelist | xargs cat > $zipfile
rm $zipfile

相关内容