在满足以下条件的情况下,我可以用文件中的另一个值代替一个值:
awk '{if (length($4)*2+1 != length($5) && $10 ~ /^1\/2/) sub("1/2","1/1"); print}' MyFile
在我的两个条件都为真的行中将“ 1/2”替换为“ 1/1”。
我的文件中有几种这样的情况,我真正想做的是在大约一半的情况下将“ 1/2”替换为“ 1/1”,而将“ 1/2”替换为“在大约另一半情况下为2/2“。也就是说,随机选择两个可能的动作sub("1/2","1/1")
或sub("1/2","2/2")
之一。这有可能吗?
非常感谢!
答案 0 :(得分:5)
awk '
length($4)*2+1 != length($5) && $10 ~ /^1\/2/ {
sub("1/2", rand() < 0.5 ? "1/1" : "2/2")
print
}
' MyFile
答案 1 :(得分:3)
每行调用rand()的问题是,最终所有sub()都相同。要保证大约一半可以做到:
awk '
BEGIN { srand() }
length($4)*2+1 != length($5) && $10 ~ /^1\/2/ {
if ( ++cnt % 2 ) {
dir = (rand() < 0.5 ? 1 : 0)
}
else {
dir = !dir
}
sub("1/2", (dir ? "1/1" : "2/2"))
}
{ print }
' MyFile
但是它的随机性要低一些,因为每第二行都与前一行相反。
答案 2 :(得分:1)
这是动态调整阈值以产生更平衡分布的另一种方法。
awk 'BEGIN {srand()}
length($4)*2+1 != length($5) && $10 ~ /^1\/2/ {
r=rand()<(1-(c1+1)/(c+2));
c1+=r; c++;
sub("1/2", r?"1/1":"2/2")}1' file
偶然地假设前三个r值为1,第四个r更有可能为0(1的概率为1-4 / 5 = 0.2而不是0.5)。这仍然不能给您准确的一半和一半的分裂。为此,更容易预先计算出确切的数字并使用shuf
。
也许也仅将sub
限制为$10
吗?