如何使用awk获得具有给定分布的随机行?

时间:2012-05-26 15:39:44

标签: awk

我有两个要合并的表格文件,但在此之前我想减少第二个。

第一个文件让我们说File1是表格式的,就像这样

 A 67 98 56
 A 22 29 62
 A 11 99 28
 B 37 88 14
 B 33 99 65

我们有3行A和2行B

File2在A和B之间包含3000行,我想从File2中随机选择行,但是与File1完全相同的A和B的数量,这意味着只有3个随机行A和2个B

任何人都知道如何用awk做到这一点?

由于

2 个答案:

答案 0 :(得分:1)

#!/bin/bash
read -r acount bcount <<< $(csplit file2 '/^B /')

awk -v "acount=$acount" -v "bcount=$bcount" '
    NR == FNR {
        arr[$1]++; 
        next
    }
    ! setup {
        setup = 1
        while (arandcount < acount) {
            line = int(rand() * acount) + 1
            if (! alines[line]) {
                alines[line] = 1
                arandcount++
            }
        }
        while (brandcount < bcount) {
            line = int(rand() * bcount) + 1
            if (! blines[line]) {
                blines[line] = 1
                brandcount++
            }
        }
    }
    FILENAME == "xx00" && FNR in alines {
        print
    }
    FILENAME == "xx01" && FNR in blines {
        print
    }' file1 xx00 xx01

其中“xx00”和“xx01”是csplit创建的文件的名称。

csplit命令将正则表达式上的输入文件拆分并输出每个输出文件的行数。 read命令将这些计数放入变量中。变量被传递到AWK程序中。

第一个块读取file1中的所有行,并计算每个“类型”(A或B)。

第二个块通过选择1和“类型”的行数之间的随机数来选择要选择的行号。由于标志,此块仅执行一次。

最后两个块检查每一行的记录编号,看它是否在拾取行号的数组中,如果是,则打印出来。

答案 1 :(得分:0)

这可能对您有用:

grep '^A' file2 | sort -R | head -$(grep -c '^A' file1) >file3
grep '^B' file2 | sort -R | head -$(grep -c '^B' file1) >>file3

N.B。假设file1已排序。