使用特定比例随机分割文件

4
我希望使用awk随机将一个文件按80/20分割。
我已经阅读并尝试了在这里找到的选项,其中提出了类似以下的建议:
$ awk -v N=`cat FILE | wc -l` 'rand()<3000/N' FILE

如果您需要随机选择,那么它非常有效。

然而,是否可能修改此awk以将一个文件分成80/20(或其他比例)的两个文件?


你说的随机80/20分割是什么意思? - fedorqui
1
例如将文件分成两部分:第一部分占80%,第二部分占20%。如果我有1000行数据,那么第一部分应该包含800行,第二部分应该包含200行,但是这800行和200行都应该是随机选择的。 - owwoow14
2
你需要精确的80/20,还是大致的80/20?如果大致相等就可以使用类似 if random(100) < 80 then write_to_file1 else write_to_file2 的模式。如果你需要精确的分割,那么你可能需要完全打乱文件中的行,然后进行切割... - twalberg
大约就可以了。但是你建议用什么语言来实现最佳呢? - owwoow14
1
@owwoow14 嗯,可能没有一种语言能产生真正的“最佳方式”。如果您想使用随机数生成器方法,显然需要在语言中提供随机数生成器和if...then...else结构... awkbashzshperlpythonrubyluaCC++FortranAdaCobol等许多语言都可以满足这个最低门槛。我的原始评论只是展示了与语言无关的伪代码模式 - 将其翻译成您选择的语言应该相当简单... - twalberg
你是否完全致力于使用awk来完成这个任务? - pjs
1个回答

12

使用gawk,你将编写如下代码:

gawk '
    BEGIN {srand()}
    {f = FILENAME (rand() <= 0.8 ? ".80" : ".20"); print > f}
' file

例子:

seq 100 > 100.txt
gawk 'BEGIN {srand()} {f = FILENAME (rand() <= 0.8 ? ".80" : ".20"); print > f}' 100.txt
wc -l 100.txt*
100 100.txt
 23 100.txt.20
 77 100.txt.80
200 total

为确保“20”文件中有20行:


$ paste -d $'\034' <(seq $(wc -l < "$file") | sort -R) "$file" \
| awk -F $'\034' -v file="$file" '{
    f = file ($1 <= 20 ? ".20" : ".80")
    print $2 > f
}'

$ wc -l "$file"*
100 testfile
 20 testfile.20
 80 testfile.80
200 total

\034 是ASCII码中的 FS 字符,很少出现在文本文件中。

sort -R 用于打乱输入的顺序,可能不太兼容。但它在GNU和BSD sort中可用。


如何适应以确保“100.txt.20”有20行,“100.txt.80”有80行? - Julio Batista Silva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接