Shell
根據源文件的順序列印隨機行
我有一個帶有短句(幾個詞長)的大文本文件(約 500K 行)。此外,大多數行中都有一些 XML 標記。最後,在添加標記之前對文本文件進行了排序!添加 XML 標記會更改字母排序,但這是需要的。
我的問題是:如何列印尊重源文件順序的隨機行?
我知道我可以只使用 shuf 命令並對結果進行排序。問題是標記會弄亂排序。
我還可以編寫一個
python
腳本,將文本文件載入到列表中,生成一些隨機數,對它們進行排序並將它們用作索引以提取行。如果可能的話,我更喜歡標準的 *nix 命令行工具。樣本數據:
<CITY>anaconda</CITY> city is in <STATE>montana</STATE> let's go to <CITY>rome</CITY> please find <CITY>berlin</CITY> where is <CITY>cairo</CITY> in <COUNTRY>egypt</COUNTRY>
例如,如果我能把2號線和3號線拉出來就好了。1,3號線和4號線也不錯。如果我得到第 3、1 和 4 行,那就不好了。
用這個:
nl file | shuf -n2 | sort -n | cut -f2-
nl
給行編號,shuf
隨機播放並將輸出限制為 2 行 (-n
),sort
重建原來的秩序,- 並
cut
刪除 的計數nl
。它將以文件的原始順序列印文件的 2 行。使用
shuf -n X
,其中X
可以是任意數字。
Donald E. Knuth 的“電腦程式藝術”第 2 卷第 3.4.2 節介紹了從文件中選擇隨機行而不進行排序(甚至不知道有多少行!)。這很容易實現,例如:
(echo foo; echo bar; echo zot) \ | perl -nle 'rand $. < 1 && ( $line = $_ ); END { print $line }'
或者 try
shuf
,它允許選擇一定數量的行,儘管因此可能比 select-one Knuth 算法需要更多的記憶體。