如何将awk rand()循环的每次迭代结果输出到独立文件中?
解决方案:用Shell循环+进程替换高效生成多组独立输出
我来帮你搞定这个问题!你现在的核心痛点是手动重复写awk命令太繁琐,而且没法自动生成多个独立的输出文件,只能得到最后一次的结果。咱们可以用Shell循环把重复逻辑封装起来,还能通过进程替换省去临时文件,一步到位生成所有你需要的out1、out2...outN文件。
优化后的完整脚本(无临时文件版)
这个版本用了Bash的进程替换特性,直接把两个awk的输出传给paste,不需要生成中间临时文件,效率更高:
#!/bin/bash # 可配置参数:按需修改这些值即可 ITERATIONS=3 # 要生成多少组输出文件(out1到out3) TOTAL_RANDOM=5 # 每组随机数的数量 MAX1=10 # 第一列随机数的最大值(0到MAX1) MAX2=20 # 第二列随机数的最大值(0到MAX2) # 循环生成每组文件 for ((i=1; i<=ITERATIONS; i++)); do paste <( # 生成第一列的随机数(去重) awk -v total="$TOTAL_RANDOM" -v max="$MAX1" ' BEGIN { srand(); count=0; delete array; # 清空数组避免残留 while(count < total) { rnd = int(rand() * max); if (!array[rnd]) { count++; array[rnd] = 1; } } # 按顺序输出选中的数 for (j=0; j<=max; j++) { if (array[j]) print j; } }' ) <( # 生成第二列的随机数(去重) awk -v total="$TOTAL_RANDOM" -v max="$MAX2" ' BEGIN { srand(); count=0; delete array; while(count < total) { rnd = int(rand() * max); if (!array[rnd]) { count++; array[rnd] = 1; } } # 按顺序输出选中的数 for (j=0; j<=max; j++) { if (array[j]) print j; } }' ) | awk '{print " "$1".0" , $2".0";}' > out$i done
关键改进点说明
- 参数化配置:把迭代次数、随机数数量、最大值都做成变量,后期修改需求直接改顶部的参数就行,不用动核心逻辑。
- Shell循环自动迭代:用
for ((i=1; i<=ITERATIONS; i++))控制生成多少组文件,每次循环输出到out$i,不会覆盖之前的文件。 - 进程替换省去临时文件:用
<()把awk的输出直接作为paste的输入,不用在磁盘上创建中间单列文件,既节省磁盘空间又提升速度。 - 数组清空保证随机性:每次awk里都用
delete array清空数组,避免意外残留数据影响随机数生成。
运行效果
执行脚本后,你会得到out1、out2...outN(N是你设置的ITERATIONS值),每个文件都是符合要求的两列数据,比如out1的内容可能是:
1.0 2.0 3.0 7.0 4.0 9.0 6.0 12.0 9.0 13.0
而out2会是另一组完全独立的随机结果,不会和out1重复。
如果需要保留中间的单列文件,也可以把进程替换改成生成临时文件的版本,不过一般来说无临时文件的版本更高效整洁。
内容的提问来源于stack exchange,提问作者Redouane Nouh
相关产品推荐
相关产品推荐

