使用AWK对一行内的单元格进行随机播放

时间:2014-04-15 13:29:37

标签: awk shuffle

我正在尝试将所有带有斜杠的列混洗(因此第5列中的所有内容都是如此)。但是,我没有到达那里,拖拽行很容易,但连续的细胞我只能解决它。必须在每一行单独进行重新洗牌。

这是我拥有的数据(这里的fiels是ordened,1/1然后是1/0等等。)

CHR1 10967叔1/1 1/1 1/1 1/0 1/0 1/0 0/0 1 /。 1 /。 0 /。 0 /。 ./。 ./。 CHR1 13241 C G 1/1 1/1 1/1 1/1 1/1 1/0 1/0 1 /。 1 /。 1 /。 1 /。 0 /。 ./.

我想随机化这个顺序(所以不是字段的实际内容,而只是它们在行中的位置)

CHR1 10967叔1/0 1 /。 1/1 1/1 1/0 1/1 0/0 1 /。 0 /。 0 /。 ./。 ./。 1/0 CHR1 13241 C G ./。 1/1 1/1 1/1 1/1 1/1 1/0 1/0 1 /。 1 /。 1 /。 1 /。 0 /.

(我自己并不是一个很好的随机发生器,但我希望这个想法很清楚)

有没有人知道如何在AWK / GAWK / NAWK中做这样的事情(我已经有一个庞大的AWK脚本,我想把它合并到一起)?我在这里找到的一个脚本很好地随机化了行,但这并不是我正在尝试做的...顺便说一下这个脚本来自https://stackoverflow.com/users/131527/ghostdog74

BEGIN{srand() }
{ lines[++d]=$0 }
END{
    while (1){
if (e==d) {break}
    RANDOM = int(1 + rand() * d)
    if ( RANDOM in lines  ){
        print lines[RANDOM]
        delete lines[RANDOM]
        ++e
    }
}
}

3 个答案:

答案 0 :(得分:1)

awk 'BEGIN{srand();OFS="   "} {for(i=5;i<=NF;i++) {k=int((NF-4)*rand()+5); j=$k; $k=$i; $i=j;} print;}' input.txt

输入:

chr1   10967   A   T   1/1   1/1   1/1   1/0   1/0   1/0  0/0   1/.   1/.   0/.   0/.   ./.   ./.
chr1   13241   C   G   1/1   1/1   1/1   1/1   1/1   1/0  1/0   1/.   1/.   1/.   1/.   0/.   ./.

输出:

chr1   10967   A   T   ./.   1/1   1/0   1/1   1/1   0/.   1/0   1/.   1/0   0/.   ./.   1/.   0/0
chr1   13241   C   G   1/1   ./.   1/0   1/0   1/.   1/1   1/1   1/.   1/1   0/.   1/1   1/.   1/.

答案 1 :(得分:1)

有一种方法,gawk&#39; asorti(),我没有用你的例子,但我不认为这对你来说是个大问题:

awk '{for(i=1;i<=NF;i++)a[i]=$i}
END{for(i in a)
        {
        x = sprintf("%.77f",rand())
        t[x] = a[i]
        }
        asorti(t,m)
        for(j=1;j<=length(m);j++)printf "%s%s", t[m[j]], (j==length(m)?"\n":FS)
}'

使用1-17进行测试:

kent$  seq -s ' ' 17|awk '{for(i=1;i<=NF;i++)a[i]=$i}
END{for(i in a)
        {
        x = sprintf("%.77f",rand())
        t[x] = a[i]
        }
        asorti(t,m)
        for(j=1;j<=length(m);j++)printf "%s%s", t[m[j]], (j==length(m)?"\n":FS)
}'
10 4 8 6 16 1 14 2 11 9 12 5 17 7 3 15 13

答案 2 :(得分:1)

这会很慢,但应该达到你想要的效果:

BEGIN {srand()}
{ for (i = 5; i <= NF; ++i)
    a[rand()] = $i
  asort(a)
  printf "%s %s %s %s", $1, $2, $3, $4
  for (i = 1; i < NF-5)
     printf " %s", a[i]
  printf "\n"
  delete a
}

我还没有真正测试过它,所以它可能不是100%正确,但基本的想法是将每个字段随机化为一个随机索引的数组,然后对数组和输出进行排序结果。