【发布时间】:2011-11-22 19:32:57
【问题描述】:
我想从包含 8000 行的 sample.file 中随机选择 3000 行。 我将使用 awk 代码或从命令行执行此操作。我怎样才能做到这一点?
【问题讨论】:
我想从包含 8000 行的 sample.file 中随机选择 3000 行。 我将使用 awk 代码或从命令行执行此操作。我怎样才能做到这一点?
【问题讨论】:
如果你有 gnu 排序,这很容易:
sort -R FILE | head -n3000
如果你有 gnu shuf,那就更简单了:
shuf -n3000 FILE
【讨论】:
-r 选项来启用替换。例如shuf -n5000 -r list-of-15-choices.txt
awk 'BEGIN{srand();}
{a[NR]=$0}
END{for(i=1; i<=3000; i++){x=int(rand()*NR) + 1; print a[x];}}' yourFile
【讨论】:
根据 Glenn 的评论修复:
awk 'BEGIN {
a=8000; l=3000
srand(); nr[x]
while (length(nr) <= l)
nr[int(rand() * a) + 1]
}
NR in nr
' infile
附:将数组传递给 length 内置函数是不可移植的,你已经被警告过 :)
【讨论】:
nr 数组后,您可能需要检查它的大小以确保您有 3000 个不同的数字。
sort / shuf 答案的不同之处在于记录将始终按照它们在原始文件中出现的顺序出现。您可能关心也可能不关心。
您可以使用awk、sort、head/tail 和sed 的组合来执行此操作,例如:
pax$ seq 1 100 | awk '
...$ BEGIN {srand()}
...$ {print rand() " " $0}
...$ ' | sort | head -5 | sed 's/[^ ]* //'
57
25
80
51
72
如您所见,它从seq 1 100 中生成的一百行中随机选择五行。
awk 技巧为文件中的每一行加上一个随机数和 "0.237788 " 格式的空格作为前缀,然后(显然)根据该随机数对其进行排序。
然后您使用head(或tail,如果您没有head)来获取第一(或最后)N 行。
最后,sed 将去掉随机数和空格以及每一行的开头。
对于您的具体情况,您可以使用类似(单行):
awk 'BEGIN {srand()} {print rand() " " $0}' file8000.txt
| sort
| tail -3000
| sed 's/[^ ]* //'
>file3000.txt
【讨论】:
我使用了这些命令,得到了我想要的:
awk 'BEGIN {srand()} {print rand() " " $0}' examples/data_text.txt | sort -n | tail -n 80 | awk '{printf "%1d %s %s\n",$2, $3, $4}' > examples/crossval.txt
实际上是从输入文件中随机选择 80 行。
【讨论】:
在 PowerShell 中:
Get-Content myfile | Get-Random -Count 3000
或更短:
gc myfile | random -c 3000
【讨论】:
如果您只需要大约 3000 行,这是一个简单的方法:
awk -v N=`cat FILE | wc -l` 'rand()<3000/N' FILE
反引号 (`) 之间的部分表示文件中的行数。
【讨论】:
对于一个我不想洗牌的大文件,这运行得很好而且非常快:
sed -u -n 'l1p;l2p; ... ;l1000p;l1000q'
-u 选项减少了缓冲,l1, l2, ... l1000 是从 R 获得的随机和排序的行号(与 python 或 perl 一样好)。
【讨论】: