2015-03-25 33 views
0

我試圖用bash中的隨機內容生成大型csv。我的機器有6個內核和12G RAM,但我的腳本(見下文)僅需要140秒,只有10k行,3列。有沒有什麼辦法來優化這個腳本?在bash中生成帶有隨機內容的大型csv

在其他語言中生成隨機csv文件是否有相當快的方法?

#!/bin/bash 

csv="foo\tbar\tbaz" 
start=$(date) 
for i in `seq 1 $1` 
    do rand=$(($i * $RANDOM)) 
    str0="$$"$i 
    str1=$(echo "$str0" | md5sum) 
    randstring1="${str1:2:8}" 
    randstring2="${str1:0:2}" 
    csv="$csv\n$randstring1\t$randstring2\t$rand" 
done 
end=$(date) 
datediff=$(($(date -d "$end" +%s) - $(date -d "$start" +%s))) 
echo -e $csv > my_csv.csv 
echo "script took $datediff seconds for $(wc -l my_csv.csv) lines" 
+1

這顯然會在編譯語言中快得多。至少,您應該儘量減少對外部工具進行的呼叫次數。我不確定性能的影響,但你也可以在循環中'echo'$ randstring1 \ t $ randstring2 \ t $ rand「'並將其重定向到輸出文件,如'done> my_csv.csv' – 2015-03-25 10:53:08

+0

[ Mockaroo](https://www.mockaroo.com/)有一個你可能感興趣的API。 – MMM 2015-03-25 10:54:58

+0

你能顯示3-4行輸出嗎? – 2015-03-25 11:28:11

回答

5

要相當精確(格式明智)代替這個腳本,你可以使用

hexdump -v -e '5/1 "%02x""\n"' /dev/urandom | 
    awk -v OFS='\t' ' 
    NR == 1 { print "foo", "bar", "baz" } 
    { print substr($0, 1, 8), substr($0, 9, 2), int(NR * 32768 * rand()) }' | 
    head -n "$1" > my_csv.csv 

這分爲三個部分:

hexdump -v -e '5/1 "%02x""\n"' /dev/urandom 

提取物5個字節/dev/urandom序列格式,然後作爲十六進制字符串,

awk -v OFS='\t' ' 
    NR == 1 { print "foo", "bar", "baz" } 
    { print substr($0, 1, 8), substr($0, 9, 2), int(NR * 32768 * rand()) }' 

適當地格式化該線,同時增加一個字段,該字段是$(($i * $RANDOM))等效和標題行,並且

head -n "$1" 

採取第一$1線的這一點。當head退出時,關閉awk的管道,關閉awk,關閉到hexdump的管道,並退出hexdump,這樣就可以使整個事情在合適的時間結束。

在我的機器上(一個Haswell i5),運行這個需要百萬行0.83秒。

+0

驚人。我的機器需要約2秒鐘1 mio線.... 只是一個問題:爲什麼'int(NR * ** 65536 ** * rand())'? – jvdh 2015-03-25 16:30:09

+1

awk的'rand()'函數返回一個介於0和1之間的值,而bash的'$ RANDOM'返回值介於... 0和32768之間,可以想到它。所以這應該是32768而不是65536,我會立即解決。 'NR'是當前行的編號,所以它與你的'i'類似。 – Wintermute 2015-03-25 17:17:32