我需要将目录中的文本文件块合并到一个或多个文件,然后压缩合并的文件。
例如:如果我在一个目录中有 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