使用linux命令随机选择列

时间:2016-03-23 20:18:58

标签: linux bash shell unix

我有一个包含606,347 的平面文件(.txt),我想提取50,000个RANDOM列,但第一列除外,它是样本标识。如何使用Linux命令执行此操作? 我的文件看起来像:

ID  SNP1    SNP2    SNP3
1   0   0   2
2   1   0   2
3   2   0   1
4   1   1   2
5   2   1   0

它是TAB分隔的。

非常感谢你。

干杯,

3 个答案:

答案 0 :(得分:3)

awk救援!

$ cat shuffle.awk

   function shuffle(a,n,k) {
     for(i=1;i<=k;i++) {
       j=int(rand()*(n-i))+i
       if(j in a) a[i]=a[j]
       else a[i]=j
       a[j]=i;
     }
   }

   BEGIN{srand(); shuffle(ar,NF,ncols)}
        {for(i=1;i<=ncols;i++) printf "%s", $(ar[i]) FS; print ""}

一般用法

$ echo $(seq 5) | awk -f shuffle.awk -v ncols=5
3 4 1 5 2

在您的特殊情况下,您可以打印$ 1并从2开始功能循环。

即。改变

for(i=1;i<=k;i++)a[1]=1; for(i=2;i<=k;i++)

答案 1 :(得分:2)

试试这个:

echo {2..606347} | tr ' ' '\n' | shuf | head -n 50000 | xargs -d '\n' | tr ' ' ',' | xargs -I {} cut -d $'\t' -f {} file

<强>更新

echo {2..606347} | tr ' ' '\n' | shuf | head -n 50000 | sed 's/.*/&p/' | sed -nf - <(tr '\t' '\n' <file) | tr '\n' '\t'

答案 2 :(得分:0)

@karakfa的答案很好,但是无法在awk脚本的BEGIN {}部分中获得NF值。请参阅:How to get number of fields in AWK prior to processing

我将代码编辑为:

head -4 10X.txt | awk '
function shuffle(a,n,k){
  for(i=1;i<=k;i++) {
    j=int(rand()*(n-i))+i
    if(j in a) a[i]=a[j]
    else a[i]=j
    a[j]=i;
  }
}
BEGIN{
  FS=" ";OFS="\t"; ncols=10;
  }NR==1{shuffle(tmp_array,NF,ncols);
    for(i=1;i<=ncols;i++){
      printf "%s", $(tmp_array[i]) OFS;
    }
    print "";
  }NR>1{
    printf "%s", $1 OFS;
    for(i=1;i<=ncols;i++){    
      printf "%s", $(tmp_array[i]+1) OFS;
    }
    print "";
    }' 

因为我正在处理单细胞基因表达谱,所以从第二行开始,第一列将是基因名称。 我的输出是:

D4-2_3095   D6-1_3010   D16-2i_1172 D4-1_337    iPSCs-2i_227    D4-2_170    D12-serum_1742  D4-1_1747   D10-2-2i_1373   D4-1_320    
Sox17   0   0   0   0   0   0   0   0   0   0   
Mrpl15  0.987862442831866   1.29176904082314    2.12650693025845    0   1.33257747910871    0   1.58815046312948    1.18541326956528    1.12103842107813    0.656789854017254   
Lypla1  0   1.29176904082314    0   0   0.443505832809852   0.780385141793088   0.57601629238987    0   0   0.656789854017254