2017-10-12 81 views
2

我有一個包含數千行的文本文件(bigfile.txt)。我想用隨機選擇的行的1%製作一個較小的文本文件。我嘗試以下從文本文件中獲取隨機選擇行的百分比

output=$(wc -l bigfile.txt) 
ds1=$(0.01*output) 
sort -r bigfile.txt|shuf|head -n ds1 

它提供以下錯誤: 頭:行數量無效:「DS1」

我不知道什麼是錯。

回答

4

即使在解決了bash腳本的問題後,也無法進行浮點運算。您需要外部工具,如Awk,我將用作

randomCount=$(awk 'END{print int((NR==0)?0:(NR/100))}' bigfile.txt) 
((randomCount)) && sort -r file | shuf | head -n "$randomCount" 

例如,寫文件與221線使用下面的循環,並試圖獲得隨機的線條,

tmpfile=$(mktemp /tmp/abc-script.XXXXXX) 
for i in {1..221}; do echo $i; done >> "$tmpfile" 
randomCount=$(awk 'END{print int((NR==0)?0:(NR/100))}' "$tmpfile") 

如果我打印的數量,它會還給我一個整數2和使用上的下一個命令,

sort -r "$tmpfile" | shuf | head -n "$randomCount" 
86 
126 
2

對於文件的每一行滾動模具(使用rand())並獲得01之間的數字。打印行,如果模具顯示小於0.01

awk 'rand()<0.01' bigFile 

快速測試 - 生成億線,看看有多少人打通:

seq 1 100000000 | awk 'rand()<0.01' | wc -l 
999308 

非常接近1%。


如果你想要的順序隨機,以及作爲選擇,您可以通過shuf通過這個算賬:

seq 1 100000000 | awk 'rand()<0.01' | shuf 

效率的這意見就這個話題,這解決方案需要24小時我的iMac 100,000,000行:

time { seq 1 100000000 | awk 'rand()<0.01' > /dev/null; } 

real 0m23.738s 
user 0m31.787s 
sys  0m0.490s 

唯一的其他解決方案在這裏工作,主要基於OP的原始代碼,需要13分鐘19秒。

+0

downvote對拼寫錯誤有點苛刻!糾正。 –

+0

我做了downvote,但對於不精確的數學而不是拼寫錯誤 - 抱歉,如果評論誤導了你。也就是說,你可以結合你的答案和其他方面 - 高估百分比,然後'shuf |頭'結果。這具有比洗牌整個輸出更高效的優點。 –

+0

@TobySpeight我不洗牌整個輸出,或兩次傳遞文件,因此它已經非常高效。事實上,我根本不洗牌,因爲OP並不要求訂單是隨機的,而只是選擇。此外,數學不是不準確的 - 當OP已經聲明他有很多線條並且可能選擇抽樣並測試大約1%的數據時,0.06%不太可能是顯着的,當時他可以很容易地選擇0.5%或2%。 –