使用awk在表格组内重复首个aa_bb开头值的技术求助
解决按组提取首条匹配值并填充新列的问题
先看你的需求:你有一份按group分组的表格数据,想要给每一行新增Modified.values列,值为对应组内第一个以aa_bb开头的Values条目。
你的原始数据是:
group Values 0 aa_bb_25_0_1 0 273 0 60 1 aa_bb_7_0_2 1 335 2 aa_bb_65_1_1 2 456 3 aa_bb_98_0_1
期望得到的结果是:
group Values Modified.values 0 aa_bb_25_0_1 aa_bb_25_0_1 0 273 aa_bb_25_0_1 0 60 aa_bb_25_0_1 1 aa_bb_7_0_2 aa_bb_7_0_2 1 335 aa_bb_7_0_2 2 aa_bb_65_1_1 aa_bb_65_1_1 2 456 aa_bb_65_1_1 3 aa_bb_98_0_1 aa_bb_98_0_1
你之前尝试的awk代码没起作用,输出和输入一致,问题出在逻辑判断上:你的代码里$3!="" {three=$2}这个条件从一开始就不成立——原始数据只有两列,$3根本不存在,所以three变量从未被赋值,后续的$3=three自然不会产生任何变化。
正确的awk解决方案
我们需要按group跟踪,当遇到当前组内第一个以aa_bb开头的Values时保存该值,之后同组的所有行都用这个值填充新列。代码如下:
BEGIN { FS="\t"; OFS="\t" } NR == 1 { print $0, "Modified.values"; next } # 处理表头,新增目标列名 $2 ~ /^aa_bb/ { current_val[$1] = $2 } # 匹配到目标行时,按group保存对应值 { print $0, current_val[$1] } # 每行输出原始内容+对应组的保存值
代码解释
BEGIN块:设置输入输出分隔符为制表符,保证表格格式对齐。- 第一行(
NR==1):单独处理表头,直接在原有表头后追加Modified.values列名,然后跳过后续逻辑避免干扰表头。 - 当第二列
$2匹配^aa_bb(以aa_bb开头)时,将这个值存入数组current_val,键为当前的group($1)——因为每个组只会在第一次匹配时赋值,后续同组的匹配行不会覆盖已有的值,刚好满足你取首个匹配值的需求。 - 最后每行都输出原始内容加上对应组的
current_val[$1]值,实现新列的填充。
直接运行这段代码(比如awk -f script.awk test.txt,或者把代码写在命令行中),就能得到你想要的结果。
内容的提问来源于stack exchange,提问作者Carol
相关产品推荐
相关产品推荐

