1)
cat filea 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
要求增加第三列为第二列的随机数:
a 1 8
b 2 6
c 3 7
d 4 4
e 5 3
f 6 9
g 7 1
h 8 5
i 9 2
- awk 'BEGIN{while("sort -k2,2 -R file"|getline)a[++i]=$2}{print $0,a[NR]}' file
[解析]
getline读shell命令是我们的老朋友啦,这次再次又它出场,先利用 sort 命令对第二字段随机排序,然后 getline 读入行,利用数组来保存随机排列的第二字段,在正常的执行中利用 NR 为下标 刚好把随机的值排列成第三字段。
- awk '{a[NR]=$0;b[NR]=$2}END{srand();while(i<NR){n=int(rand()*NR)+1;if(!c[n]++){i++;d[i]=b[n]}};for(i=1;i<=NR;i++)print a[i],d[i]}' file
[解析]
这是利用awk本身的随机函数进行操作,srand()函数以时间为种子,保证每次取的随机数不一样,否则rand()只随机一次。rand()函数是取0~1之间的随机小数,这里乘以NR,取整后会得到 0~(NR-1) 之间的随机整数,再+1,得到 1~NR 之间的随机出现的整数,注意这个数可能是重复的,所以利用了数组c来取重,最后利用数组d来保存这些随机数,最后用for循环输出。总的来说效率比较低,特别是在行数多的情况下,求哈希值,哈希冲撞的机会大大增加,效率就会降低。
2)
cat file
aaaaaaa
bbbbbbb
ddddddd
eeeeeee
将第2-4位的替换成随机数:
a136aaa
b569bbb
d906ddd
e661eee
- awk 'BEGIN{srand(systime())}{r=sprintf("%03d",int(rand()*1000));$0=gensub(/(.).../,"\\1"r"",$0)}1' file
[解析]
这里注意几个问题,第一是构建三位的随机数,乘以1000取整也不一定能取到3位自然数。所以这里用 sprintf 把取整不足100的用零填充为3位。然后用 gensub 替换字符串。不能使用这样的语句
sub(substr($0,2,3),r,$0) ,因为都是一样的字符串,不能按所想的替换2 3 4位字符。
阅读(5619) | 评论(0) | 转发(2) |