按照源文件的顺序打印随机行

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可以是任意数字。

  • 我喜欢这个解决方案! (2认同)

thr*_*rig 7

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 算法更多的内存。


Eri*_*ouf 5

您可以使用 while 循环和 $RANDOM 来完成,例如:

while read line; do
    if ((RANDOM%2)); then
        echo $line;
    fi;
done < _path_
Run Code Online (Sandbox Code Playgroud)

这将打印大约一半的行,您可以使用 if