如何使用 sed 替换一行中的两个匹配模式?

如何使用 sed 替换一行中的两个匹配模式?

总结

鉴于这种:

$ echo "-lngtcp2_crypto_openssl -lnghttp2.14 -lnghttp2 -lnghttp3.0" | \
    sed "s: -lnghttp2[^[:space:]]* : lib/libnghttp2.a :g"
-lngtcp2_crypto_openssl lib/libnghttp2.a -lnghttp2 -lnghttp3.0

为什么不将-lnghttp2.14-lnghttp2替换为lib/libnghttp2.a?该参数不应该:g让 sed 替换两者吗?

较长版本

我需要用-l<library>相应的路径替换命令中的行.a。我已经知道路径了,所以我认为这应该可以通过一系列简单的 sed 命令来完成。但我遇到了一个问题,我可以像这样最低限度地重现它:

$ echo "-lngtcp2_crypto_openssl -lnghttp2.14 -lnghttp2 -lnghttp3.0" | \
    sed "s: -lnghttp2[^[:space:]]* : lib/libnghttp2.a :g"
-lngtcp2_crypto_openssl lib/libnghttp2.a -lnghttp2 -lnghttp3.0

这个输出不是我期望的。我希望将 和 都-lnghttp2.14替换-lnghttp2lib/libnghttp2.a。因此,我想要这样的输出:

-lngtcp2_crypto_openssl lib/libnghttp2.a lib/libnghttp2.a -lnghttp3.0

而只是被替换。我注意到,如果我切换和-lnghttp2.14的顺序,那么,同样,只有两个 nghttp2 库的第一次出现被替换。我以为sed 的参数会替换多个匹配模式,但它似乎并没有为我做到这一点。有人能帮我想出正确的 sed 调用方法,将这两个都替换为所需的路径吗?-lnghttp2.14-lnghttp2g.a

我已经在 MacOS 和 Centos 8 上复现了这个问题。

答案1

我的问题是,我的搜索模式在 的两边都有空格-l<library>。由于这个限制,只有第一个匹配,因为第二个没有前面的空格。如果我删除前面的空格,那么两个词都会被匹配和替换。因此:

$ echo "-lngtcp2_crypto_openssl -lnghttp2.14 -lnghttp2 -lnghttp3.0" | \
    sed "s:-lnghttp2[^[:space:]]* :lib/libnghttp2.a :g"
-lngtcp2_crypto_openssl lib/libnghttp2.a lib/libnghttp2.a -lnghttp3.0

相关内容