Bash

連接文件的最快方法

  • June 9, 2020

我有 10k+ 個文件,總計超過 20GB,我需要將它們連接成一個文件。

有沒有比

cat input_file* >> out

?

首選方式是 bash 命令,Python 也是可以接受的,如果不是相當慢的話。

不,貓肯定是最好的方法。如果已經為此目的用 C 編寫了一個程序,為什麼還要使用 python?但是,如果xargs命令行長度超過ARG_MAX並且您需要多個cat. 使用 GNU 工具,這相當於您已經擁有的:

find . -maxdepth 1 -type f -name 'input_file*' -print0 |
 sort -z |
 xargs -0 cat -- >>out

首先為輸出文件分配空間可能會提高整體速度,因為系統不必為每次寫入更新分配。

例如,如果在 Linux 上:

size=$({ find . -maxdepth 1 -type f -name 'input_file*' -printf '%s+'; echo 0;} | bc)
fallocate -l "$size" out &&
 find . -maxdepth 1 -type f -name 'input_file*' -print0 |
 sort -z | xargs -r0 cat 1<> out

另一個好處是,如果沒有足夠的可用空間,將不會嘗試複製。

如果 on btrfs,您可以創建copy --reflink=always第一個文件(這意味著沒有數據複製,因此幾乎是即時的),然後附加其余文件。如果有 10000 個文件,除非第一個文件很大,否則這可能不會有太大區別。

有一個 API 可以概括它來引用複制所有文件(BTRFS_IOC_CLONE_RANGE ioctl),但我找不到任何公開該 API 的實用程序,所以你必須用 C (python或其他語言,只要它們可以呼叫任意ioctls ) .

如果源文件是稀疏的或具有大量 NUL 字元序列,您可以使用(在 GNU 系統上)製作稀疏輸出文件(節省時間和磁碟空間):

find . -maxdepth 1 -type f -name 'input_file*' -print0 |
 sort -z | xargs -r0 cat | cp --sparse=always /dev/stdin out

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