![打印尊重源文件顺序的随机行](https://linux22.com/image/70941/%E6%89%93%E5%8D%B0%E5%B0%8A%E9%87%8D%E6%BA%90%E6%96%87%E4%BB%B6%E9%A1%BA%E5%BA%8F%E7%9A%84%E9%9A%8F%E6%9C%BA%E8%A1%8C.png)
我有一个很大的文本文件(~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 行,那就不好了。
答案1
用这个:
nl file | shuf -n2 | sort -n | cut -f2-
nl
对行进行编号,shuf
打乱顺序并将输出限制为 2 行 (-n
),sort
重建原来的秩序,- 并
cut
删除 的计数nl
。
它将按照文件的原始顺序打印文件的 2 行。使用shuf -n X
, 其中X
可以是任意数字。
答案2
Donald E. Knuth 的《计算机编程艺术》第 2 卷第 3.4.2 节介绍了从文件中选择随机行而不进行排序(甚至不知道有多少行!)的内容。这实现起来很简单,例如:
(echo foo; echo bar; echo zot) \
| perl -nle 'rand $. < 1 && ( $line = $_ ); END { print $line }'
或者尝试shuf
,它允许选择一定数量的行,尽管因此可能比选择一个 Knuth 算法需要更多的内存。
答案3
您可以使用 while 循环和 $RANDOM 来完成此操作,如下所示:
while read line; do
if ((RANDOM%2)); then
echo $line;
fi;
done < _path_
这将打印大约一半的行,您可以使用条件中的控制if