AWK先后匹配identifier与type双模式插入文本的问题解决
问题根源
- awk 变量不能直接放在正则定界符
//中匹配,你写的/ITEM/只会匹配字面量字符串ITEM,不会读取你传入的ITEM变量值 - 原匹配字符串未对齐原JS文件的空格格式,导致匹配失败
- 原有插入逻辑会全局匹配所有
'type': [,会误插入到其他产品的type数组中,未限定在目标产品的update块内
修复后完整脚本
FILE_PATH="./dbScripts/products.js" # 输入示例:COFFEE echo "Enter product identifier" read -r PRODUCT_IDENTIFIER # 这里替换成你实际要插入的品牌信息 BRAND_NAME="Nescafe" BRAND_IDENTIFIER="COFFEE_NESCAFE" BRAND_DESC="Coffee by Nescafe" # 第一步:检测目标product是否存在,同时完成插入操作,避免多次读取文件 awk -v prod_id="'$PRODUCT_IDENTIFIER'" \ -v brand_name="'$BRAND_NAME'" \ -v brand_id="'$BRAND_IDENTIFIER'" \ -v brand_desc="'$BRAND_DESC'" \ ' # 初始化匹配标记 BEGIN { in_target_block = 0 inserted = 0 } # 匹配到目标identifier的行,标记进入目标块 $0 ~ "{ *'\''identifier'\'': *" prod_id " *}" { in_target_block = 1 } # 目标块内匹配到type数组开头,且还未插入的话,插入新品牌对象 in_target_block == 1 && inserted == 0 && /'\''type'\'': *\[/ { print $0 # 插入新对象,格式后续由prettier处理直接写就行 print " {\n '\''name'\'': " brand_name ",\n '\''identifier'\'': " brand_id ",\n '\''desc'\'':\n " brand_desc "\n }," inserted = 1 next } # 遇到update语句结束的行,重置块标记 /\{ *upsert: *true *\} *\)/ { in_target_block = 0 } # 输出所有原有行 1 ' "$FILE_PATH" > "${FILE_PATH}_tmp" && mv "${FILE_PATH}_tmp" "$FILE_PATH" # 如果你需要单独判断是否存在来走创建逻辑,可以单独提取匹配结果 PROD_EXISTS=$(awk -v prod_id="'$PRODUCT_IDENTIFIER'" '$0 ~ "{ *'\''identifier'\'': *" prod_id " *}" {print 1;exit} END {print 0}' "$FILE_PATH") if [ "$PROD_EXISTS" -eq 0 ]; then # 这里放你已经实现的创建完整记录的逻辑 echo "Product not found, create new record" fi
改动说明
- 直接通过一次awk调用完成匹配检测+插入操作,避免多次IO读取文件
- 用
$0 ~ 变量的方式做动态正则匹配,符合awk的语法规则 - 新增块匹配逻辑,只会在目标product的update块内寻找
type数组,不会误修改其他产品的内容 - 正则中加了
*匹配任意数量空格,兼容文件中可能存在的格式差异
内容的提问来源于stack exchange,提问作者MorbidScroll
相关产品推荐
相关产品推荐

