如何在shell脚本中转​​义sed

时间:2017-06-06 09:56:55

标签: shell sed

我有正则表达式"myname"(?:(?:.*\n)+).*tree_ish = "(.*)",,它适用于自身(在https://regex101.com/中测试):

    name = "myname",
    dummy1 = 2345,
    dummy2 = "dummy",
    tree_ish = "bc59c4f7c7cf4d0b969a3f405a4a5b7fee22ae96",

现在我想在 sed 中使用该正则表达式来替换一个字幕组,但无法找出正确的转义。我试图逃避所有\().*+,但不知道两种排列都没有奏效。遗憾的是,使用sed并不像以下那样容易:

sed -i 's|"myname"(?:(?:.*\n)+).*tree_ish = "(.*)",|rEpLaCe|' myfile

有人知道用bc59c4f7c7cf4d0b969a3f405a4a5b7fee22ae96替换rEpLaCe会有什么正确的转义吗?

预期产出:

    name = "myname",
    dummy1 = 2345,
    dummy2 = "dummy",
    tree_ish = "rEpLaCe",

1 个答案:

答案 0 :(得分:2)

awk更适合

$ awk '/"myname"/{f=1} /tree_ish/ && f{sub(/"[^"]+"/,"\"rEpLaCe\"");f=0} 1' ip.txt 
    name = "myname",
    dummy1 = 2345,
    dummy2 = "dummy",
    tree_ish = "rEpLaCe",
    如果行包含/"myname"/{f=1} ,则
  • "myname"设置一个标记
  • /tree_ish/ && f如果行包含tree_ish并且设置了标志
    • sub(/"[^"]+"/,"\"rEpLaCe\"")将双引号之间的内容更改为"rEpLaCe"
    • f=0清除旗帜
  • 1打印输入行的惯用方法,包括所做的任何更改
  • 这里有很多假设,比如只有一个双引号值,没有使用锚点等等。相应地更改它们


如果PCRE更舒服,那么可能使用

$ perl -0777 -pe 's/"myname".*?tree_ish\h*=\h*"\K[^"]+(?=")/rEpLaCe/sg' ip.txt 
    name = "myname",
    dummy1 = 2345,
    dummy2 = "dummy",
    tree_ish = "rEpLaCe",