Linux

如何為一個巨大的文件夾創建多 tar 檔案

  • September 2, 2020

我有一個包含 30M 小文件的大文件夾。我希望將文件夾備份到 30 個檔案中,每個 tar.gz 文件將有 1M 個文件。拆分成多個檔案的原因是解壓一個大檔案需要一個月的時間。管道 tar 拆分也不起作用,因為當解壓文件時,我必須將所有檔案集中在一起。

另外,我希望不要將每個文件 mv 到一個新的目錄,因為即使是 ls 對於這個巨大的文件夾也是非常痛苦的。

我寫了這個 bash 腳本來做到這一點。它基本上形成一個數組,其中包含要進入每個 tar 的文件的名稱,然後在所有文件tar並行啟動。這可能不是最有效的方法,但它會按照您的意願完成工作。我可以預期它會消耗大量記憶體。

您將需要調整腳本開頭的選項。您可能還想更改cvjf最後一行中的 tar 選項(例如刪除詳細輸出v以提高性能或將壓縮更改jz等…)。

腳本

#!/bin/bash

# User configuratoin
#===================
files=(*.log)           # Set the file pattern to be used, e.g. (*.txt) or (*)
num_files_per_tar=5 # Number of files per tar
num_procs=4         # Number of tar processes to start
tar_file_dir='/tmp' # Tar files dir
tar_file_name_prefix='tar' # prefix for tar file names
tar_file_name="$tar_file_dir/$tar_file_name_prefix"

# Main algorithm
#===============
num_tars=$((${#files[@]}/num_files_per_tar))  # the number of tar files to create
tar_files=()  # will hold the names of files for each tar

tar_start=0 # gets update where each tar starts
# Loop over the files adding their names to be tared
for i in `seq 0 $((num_tars-1))`
do
 tar_files[$i]="$tar_file_name$i.tar.bz2 ${files[@]:tar_start:num_files_per_tar}"
 tar_start=$((tar_start+num_files_per_tar))
done

# Start tar in parallel for each of the strings we just constructed
printf '%s\n' "${tar_files[@]}" | xargs -n$((num_files_per_tar+1)) -P$num_procs tar cjvf

解釋

首先,與所選模式匹配的所有文件名都儲存在數組中files。接下來,for 循環對該數組進行切片並從切片中形成字元串。切片的數量等於所需的 tarball 的數量。結果字元串儲存在數組中tar_files。for 循環還將生成的 tarball 的名稱添加到每個字元串的開頭。的元素tar_files採用以下形式(假設 5 個文件/tarball):

tar_files[0]="tar0.tar.bz2  file1 file2 file3 file4 file5"
tar_files[1]="tar1.tar.bz2  file6 file7 file8 file9 file10"
...

腳本的最後一行,xargs用於啟動多個tar程序(直到指定的最大數量),每個程序將tar_files並行處理數組的一個元素。

測試

文件清單:

$ls

a      c      e      g      i      k      m      n      p      r      t
b      d      f      h      j      l      o      q      s

生成的壓縮包: $ls /tmp/tar* tar0.tar.bz2 tar1.tar.bz2 tar2.tar.bz2 tar3.tar.bz2

引用自:https://unix.stackexchange.com/questions/197464