如何用sed/awk匹配首尾为XX的字符串并替换为指定格式?
解决AWK中匹配XX开头XX结尾字符串并替换为${hf:原字符串}的问题
你遇到的核心问题是AWK的gensub函数引用匹配内容的方式不对,之前用$A是无效的语法,AWK里有专门的规则来引用匹配到的内容。下面给你两种可行的解决方法,分别用AWK和SED实现,都能精准满足你的需求:
方法一:使用AWK实现全局替换
AWK的gensub函数可以通过&直接引用整个匹配到的字符串,或者用捕获组\\n来指定引用分组。这里我们用非贪婪匹配XX.*?XX来精准定位每个独立的XX...XX片段(避免误匹配多个连在一起的目标字符串),加上"g"参数实现全局替换:
awk '{print gensub(/XX.*?XX/, "${hf:&}", "g")}' test.hql
如果想用捕获组的方式更明确,也可以写成:
awk '{print gensub(/(XX.*?XX)/, "${hf:\\1}", "g")}' test.hql
这里(XX.*?XX)是第一个捕获组,\\1用来引用这个分组的内容(注意AWK里需要双转义反斜杠,才能被正确解析)。
方法二:使用SED实现全局替换
如果你更习惯用SED,同样可以用&来引用匹配到的整个字符串,结合扩展正则表达式实现:
sed -E 's/XX.*?XX/${hf:&}/g' test.hql
-E参数启用扩展正则表达式,让我们可以直接用.*?做非贪婪匹配(GNU SED默认支持该语法,部分其他版本如果不支持,可改用XX[^X]*XX——前提是确定目标字符串中间没有单独的X字符)。
为什么之前的命令失效?
你之前用$A是错误的语法:AWK里没有$A这种引用匹配内容的方式,它会被当成普通字符串直接输出,所以才会出现替换结果里保留$A的问题。正确的引用方式是&(代表整个匹配内容)或者\\n(代表第n个捕获组的内容)。
测试验证
用你的输入示例测试上述命令,会得到完全符合期望的输出:
输入:
CREATE TABLE XX_DB_XX.test_XX_YYYYMMDD_XX AS SELECT id FROM XX_R_DB_XX.usr_XX_YYYYMMDD_XX WHERE year = XX_YYYY_XX AND month = XX_MM_XX AND day = XX_DD_XX;输出:
CREATE TABLE ${hf:XX_DB_XX}.test_${hf:XX_YYYYMMDD_XX} AS SELECT id FROM ${hf:XX_R_DB_XX}.usr_${hf:XX_YYYYMMDD_XX} WHERE year = ${hf:XX_YYYY_XX} AND month = ${hf:XX_MM_XX} AND day = ${hf:XX_DD_XX};
内容的提问来源于stack exchange,提问作者Sampat Kumar
相关产品推荐
相关产品推荐

