如何将含正向预查的正则转换为sed可用操作:替换每行首个=前的所有-为_
替换每行第一个=前的所有-为_(sed/awk实现)
我懂你这个痛点——sed确实不支持正向预查,哪怕加了-r(扩展正则)参数也没用。不过咱们不用死磕预查,换个思路就能实现需求:把每行拆成=之前和之后的两部分,只处理前半段的-,再拼回去就行。
先确认你的测试数据和期望输出:
测试输入:
ke-y_0-1="foo" key_two="bar" key_03-three="baz-jazz-mazz" key-="rax_foo" key-05-five="craz-"期望输出:
ke_y_0_1="foo" key_two="bar" key_03_three="baz-jazz-mazz" key_="rax_foo" key_05_five="craz-"
Sed 实现方案
sed虽然不支持正向预查,但可以用循环替换的方式,精准处理=之前的所有-:
sed -r ':loop; s/^([^=]*)-/\1_/; t loop' dataset.txt
命令解释:
:loop:定义一个名为loop的标记点,用来重复执行替换操作s/^([^=]*)-/\1_/:匹配从行首到第一个=之前的任意内容([^=]*表示非=的所有字符),后面紧跟一个-,把这个-替换成_t loop:如果上一次替换成功了,就跳回loop标记继续循环,直到=之前没有-可替换为止
这个命令会循环处理每行的前半段,直到所有-都换成_,完全不会触动=之后的内容。
Awk 实现方案
awk处理这种分割替换的场景更直观,逻辑一目了然:
awk '{ # 定位第一个=的位置 eq_position = index($0, "=") # 提取=之前的部分,替换所有-为_ first_part = substr($0, 1, eq_position - 1) gsub(/-/, "_", first_part) # 提取=及之后的部分,拼接输出 second_part = substr($0, eq_position) print first_part second_part }' dataset.txt
如果想要更简洁的单行版本:
awk '{eq=index($0,"="); f=substr($0,1,eq-1); gsub(/-/,"_",f); print f substr($0,eq)}' dataset.txt
命令解释:
index($0, "="):找到第一个=在当前行的位置substr($0, 1, eq_position - 1):截取=之前的所有字符gsub(/-/, "_", first_part):把前半段里的所有-替换成_- 最后把处理后的前半段和原行的
=及后面内容拼接输出,完美保留后半段的原始格式
不管用sed还是awk的方案,都能精准得到你想要的处理结果。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

