如何在sentry.tmp文件中为指定前缀字段添加对应前缀字符串
解决sentry.tmp文件路径前缀批量替换问题
首先,你的需求很明确:给sentry.tmp第二列的不同前缀分别加上databases/或databases_users/,但原脚本有几个关键问题导致无法正常工作:
原脚本的问题分析
- 文件覆盖/追加逻辑错误:循环里每次用
> sentry.new会直接覆盖之前的结果,只有最后一次循环的修改会保留;如果用>>又会导致每行被多次修改后重复追加,最终结果完全混乱。 - Awk变量引用错误:
gsub(/$basedatos/,"databases/$basedatos")里的正则表达式用单引号包裹,Awk不会解析其中的$basedatos变量,会把它当成字面量字符串;同时替换目标里的$basedatos也不会被替换成实际变量值。 - 重复修改同一行:循环遍历每个前缀时,会多次修改同一行内容,导致错误的嵌套替换。
高效解决方案:单Awk脚本搞定
其实不需要写shell循环,用Awk一次性读取init.txt构建映射关系,再处理sentry.tmp即可,代码更简洁高效:
awk ' # 第一步:读取init.txt,构建前缀到目标路径的映射 NR == FNR { if ($0 ~ /_up$/) { prefix_map[$0] = "databases/" $0 } else { prefix_map[$0] = "databases_users/" $0 } next } # 第二步:处理sentry.tmp文件,替换第二列的前缀 { for (prefix in prefix_map) { # 检查第二列是否以当前前缀开头(后面跟/,避免部分匹配) if ($2 ~ "^" prefix "/") { sub("^" prefix, prefix_map[prefix], $2) break # 找到匹配的前缀就停止,避免多次替换 } } print $0 } ' init.txt sentry.tmp > sentry.new
脚本说明
NR == FNR:这个条件只会在处理第一个文件(init.txt)时触发,我们把每个前缀对应的目标路径存在prefix_map数组里。- 处理
sentry.tmp时,遍历所有前缀,检查第二列是否以该前缀开头(加上/是为了避免类似docliente匹配到docliente_up的情况),找到匹配项就替换前缀,然后打印整行。
验证结果
运行上面的脚本后,sentry.new的内容会完全符合你的预期:
8272275 databases/docliente_up/ant_aux_secciones_mes2 556321 8272276 databases/docliente_up/ant_aux_ufcp_mes1 556322 8272278 databases/docliente_up/ant_aux_ufcp_mes2 556324 8272460 databases/docliente_up/jmn_sms_sevilla 556471 8837577 databases_users/docliente_bu/do_acumulacion/fecha=20190502 550972 8837578 databases_users/docliente_tres/do_acumulacion/fecha=20190524 550972 8837579 databases_users/docliente/do_acumulacion/fecha=20190503 550972
内容的提问来源于stack exchange,提问作者Skiel
相关产品推荐
相关产品推荐

