要生成大量隨機大小的文件,最簡單的方法是for迴圈N次。 例如,生成100W個0 16K大小的小文件(嘗試時請改小一點數量,不然時間要很久): tmp_dir=/tmp/temp for i in {1..1000000};do dd if=/dev/zero of=$tmp_dir/${i}.lo ...
要生成大量隨機大小的文件,最簡單的方法是for迴圈N次。
例如,生成100W個0-16K大小的小文件(嘗試時請改小一點數量,不然時間要很久):
tmp_dir=/tmp/temp
for i in {1..1000000};do
dd if=/dev/zero of=$tmp_dir/${i}.log bs=`shuf -n 1 -i 0-16`k count=1 &>/dev/null
done
這裡使用dd命令從/dev/zero中取數據填充小文件,其中tmp_dir變數是存放大量小文件的目錄,文件的隨機大小由shuf命令生成。
但是這樣會非常的慢,不僅占用大量IO,操作系統還繁忙地open、close文件描述符。這樣的創建方式效率極低。
為了不頻繁open、close文件描述符,可以直接將創建的文件放進壓縮包中,比如cpio、tar(但不要加數據壓縮功能,如zip、xz等,因為壓縮會占用大量cpu進行計算),等給定數量的文件創建完後再解壓這個壓縮包。這種方式在shell中實現起來比較複雜。
更好的方式是使用split命令,它可以將文件按給定大小均勻切分成小文件。這裡可以使用/dev/zero作為數據源。
因為split只能切分成等大小的文件,所以大小無法隨機,只能在一定數量的迴圈下,多次切分成等隨機大小的文件。正如下麵的for和shuf。
tmp_dir=/tmp/temp
for i in {1..100};do
dd bs=10000 count=8192 if=/dev/zero |\
split -b `shuf -n 1 -i 1-16`k -a 5 -d - "$tmp_dir/$i-"
done
每次迴圈中,dd每次生成8192*10000=8.2M的數據源,這8.2M的數據供split進行分割,分隔的每個文件都由shuf
確定,比如某次shuf的值為5,那麼8.2M的數據全部切分成5k大小的文件共16000個小文件。這樣的操作迴圈100次。
這樣的方式非常快,但是只迴圈了100次,shuf的隨機數分配不夠均勻,所以無法控制文件的數量,比如上面的命令可能會生成200W個文件,如果運氣差可能生成400W個文件。
改成下麵的,迴圈次數增加一些,每次數據源大小小一點:
for i in {1..10000};do
dd bs=100 count=8192 if=/dev/zero |\
split -b `shuf -n 1 -i 1-16`k -a 3 -d - "$i-"
done
生成100W個文件大概需要5分鐘(普通固態下)。同樣的,文件數量不可控制。