Vla*_*ecs 6 shell sed awk sort random
我有一个包含短句(几个字长)的大文本文件(~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>
Run Code Online (Sandbox Code Playgroud)
例如,如果我能拉出第 2 和第 3 行就太好了。第 1,3 和 4 行也不错。如果我得到第 3、1 和 4 行,那就不好了。
cha*_*aos 16
用这个:
nl file | shuf -n2 | sort -n | cut -f2-
Run Code Online (Sandbox Code Playgroud)
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 }'
Run Code Online (Sandbox Code Playgroud)
或者 try shuf
,它允许选择一定数量的行,但可能因此需要比选择一个 Knuth 算法更多的内存。
您可以使用 while 循环和 $RANDOM 来完成,例如:
while read line; do
if ((RANDOM%2)); then
echo $line;
fi;
done < _path_
Run Code Online (Sandbox Code Playgroud)
这将打印大约一半的行,您可以使用 if