Linux 如何以高效内存的方式随机化行?

Linux 如何以高效内存的方式随机化行?,linux,bash,unix,awk,Linux,Bash,Unix,Awk,我有一个如下所示的文本,大小约为6gb。我想保持行高达#CHROM不变,但我想洗牌行#CHROM下面的所有行。有没有一种内存有效的方法可以做到这一点 ##contig=<ID=chrX,length=155270560,assembly=hg19> ##contig=<ID=chrY,length=59373566,assembly=hg19> ##contig=<ID=chrM,length=16571,assembly=hg19> ##reference=

我有一个如下所示的文本,大小约为6gb。我想保持行高达
#CHROM
不变,但我想洗牌行
#CHROM
下面的所有行。有没有一种内存有效的方法可以做到这一点

##contig=<ID=chrX,length=155270560,assembly=hg19>
##contig=<ID=chrY,length=59373566,assembly=hg19>
##contig=<ID=chrM,length=16571,assembly=hg19>
##reference=file:///dmf/
##source=SelectVariants
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT
chr1    14165   .       A       G       220.12  VQSRTrancheSNP99.90to10
chr1    14248   .       T       G       547.33  VQSRTrancheSNP99.90to10
chr1    14354   .       C       A       2942.62 VQSRTrancheSNP99.90to10
chr1    14374   .       A       G       17.90   VQSRTrancheSNP99.90to10
##contig=
##挫伤=
##挫伤=
##参考文献=file:///dmf/
##source=SelectVariants
#CHROM POS ID REF ALT QUAL过滤器信息格式
CHR14165。A G 220.12 VQSRTrancheSNP99.90至10
CHR14248。T G 547.33 VQSRTrancheSNP99.90至10
CHR114354。C A 2942.62 VQSRTrancheSNP99.90至10
CHR114374。A G 17.90 VQSRTrancheSNP99.90至10
我想要的结果如下所示:

##contig=<ID=chrX,length=155270560,assembly=hg19>
##contig=<ID=chrY,length=59373566,assembly=hg19>
##contig=<ID=chrM,length=16571,assembly=hg19>
##reference=file:///dmf/
##source=SelectVariants
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT
chr1    14354   .       C       A       2942.62 VQSRTrancheSNP99.90to10
chr1    14248   .       T       G       547.33  VQSRTrancheSNP99.90to10
chr1    14374   .       A       G       17.90   VQSRTrancheSNP99.90to10
chr1    14165   .       A       G       220.12  VQSRTrancheSNP99.90to10
##contig=
##挫伤=
##挫伤=
##参考文献=file:///dmf/
##source=SelectVariants
#CHROM POS ID REF ALT QUAL过滤器信息格式
CHR114354。C A 2942.62 VQSRTrancheSNP99.90至10
CHR14248。T G 547.33 VQSRTrancheSNP99.90至10
CHR114374。A G 17.90 VQSRTrancheSNP99.90至10
CHR14165。A G 220.12 VQSRTrancheSNP99.90至10

我会按照您的标准分割文件,在第二个块上使用
shuf
,然后再次将它们组合在一起。我想不出一个内存高效的wat可以避免拆分。

我会按照您的标准拆分文件,在第二个块上使用
shuf
,然后再次将它们组合在一起。我想不出一个内存高效的wat可以避免拆分。

这里是awk中的一个:

awk -v seed=$RANDOM '              # get a random seed to srand()
BEGIN {
    srand(seed)                    
}
/^#/ {                             # print all # starting, no need to store them to mem
    print                          # this could be more clever but not the point
    next                           # in this solution
}
{
    r=rand()                        # get a random value for hash key
    a[r]=a[r] (a[r]==""?"":ORS) $0  # hash to a, append if key collision
}
END {
    for(i in a)                     # in the end print in awk implementation default order
        print a[i]                  # randomness was created while hashing
}' file
输出:

##contig=<ID=chrX,length=155270560,assembly=hg19>
##contig=<ID=chrY,length=59373566,assembly=hg19>
##contig=<ID=chrM,length=16571,assembly=hg19>
##reference=file:///dmf/
##source=SelectVariants
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT
chr1    14165   .       A       G       220.12  VQSRTrancheSNP99.90to10
chr1    14354   .       C       A       2942.62 VQSRTrancheSNP99.90to10
chr1    14248   .       T       G       547.33  VQSRTrancheSNP99.90to10
chr1    14374   .       A       G       17.90   VQSRTrancheSNP99.90to10
因为我使用的
NR
也包括
#
起始记录,所以1000条记录不是散列中记录的确切数量。选择一个你喜欢的值

下面是一个带有
NR>10
seq 1 20
的示例输出:

$ seq 1 20 | awk -v seed=$RANDOM -f script.awk  
3
9
13
2
1
16
17
14
10
20
15
7
19
5
18
12
11
6
4
8
以下是awk中的一个:

awk -v seed=$RANDOM '              # get a random seed to srand()
BEGIN {
    srand(seed)                    
}
/^#/ {                             # print all # starting, no need to store them to mem
    print                          # this could be more clever but not the point
    next                           # in this solution
}
{
    r=rand()                        # get a random value for hash key
    a[r]=a[r] (a[r]==""?"":ORS) $0  # hash to a, append if key collision
}
END {
    for(i in a)                     # in the end print in awk implementation default order
        print a[i]                  # randomness was created while hashing
}' file
输出:

##contig=<ID=chrX,length=155270560,assembly=hg19>
##contig=<ID=chrY,length=59373566,assembly=hg19>
##contig=<ID=chrM,length=16571,assembly=hg19>
##reference=file:///dmf/
##source=SelectVariants
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT
chr1    14165   .       A       G       220.12  VQSRTrancheSNP99.90to10
chr1    14354   .       C       A       2942.62 VQSRTrancheSNP99.90to10
chr1    14248   .       T       G       547.33  VQSRTrancheSNP99.90to10
chr1    14374   .       A       G       17.90   VQSRTrancheSNP99.90to10
因为我使用的
NR
也包括
#
起始记录,所以1000条记录不是散列中记录的确切数量。选择一个你喜欢的值

下面是一个带有
NR>10
seq 1 20
的示例输出:

$ seq 1 20 | awk -v seed=$RANDOM -f script.awk  
3
9
13
2
1
16
17
14
10
20
15
7
19
5
18
12
11
6
4
8

因为您使用的是Linux,所以您可能有GNU
sort-R
来随机化


GNU sort将在需要时自动使用磁盘空间而不是RAM,因此它可以在RAM少得多的系统上对数百GB字节进行排序/随机化。

因为您使用的是Linux,所以您可能有GNU
sort-R
进行随机化


GNU sort将在需要时自动使用磁盘空间而不是RAM,因此它可以在RAM少得多的系统上对数百GB字节进行排序/随机化。

谢谢!如果行数超过37000行,
shuf
shuf是否会降低?我还没有对那么大的文件操作过shuf,我不知道。但由于它是coreutils的一部分,我至少要试一试;)谢谢如果行数超过37000行,
shuf
shuf是否会降低?我还没有对那么大的文件操作过shuf,我不知道。但由于它是coreutils的一部分,我至少要试一试;)可能会很有趣。这取决于您最终将如何使用这些行,以及您希望它们具有多大的随机性。如果允许某些局部关联,则可以对数据部分进行分块,对每个部分进行shuf并以随机顺序连接这些分块。可能会很有趣。这取决于您最终将如何使用这些行,以及您希望它们具有多大的随机性。如果允许某些局部关联,您可以对数据部分进行分块,对每个数据块进行shuf,并以随机顺序连接这些分块。该算法将有利于早期记录提前显示,而不是接近统一。例如,
20
将在第一行显示零更改。确定。如果你有足够的内存,可以运行一个完整的随机版本,或者运行一到几次节省内存的版本。这种算法有利于早期记录提前显示,而不是接近统一。例如,
20
将在第一行显示零更改。确定。如果您有内存,请运行完整的随机版本,或者运行一到几次内存节省版本。