【问题标题】:replacing a path with sed用 sed 替换路径
【发布时间】:2011-01-24 15:35:55
【问题描述】:

如何使用 sed 替换这一行

char * path_list_[1] = { "/some/random/path" };

用这条线

char * path_list_[2] = { "lib/foo", "lib/bar" };

在名为 source.c 的文件中

注意事项:
* 路径真的很随机​​。
* 您的解决方案应该只更改 source.c 中的这一行
* 我只对 sed oneliner 感兴趣。

您可以使用这个 Python 正则表达式作为起点:

text = re.sub('static const char \* path_list_\[1\] = \{ "[^"]*" \};', 
    'static const char * path_list_[2] = { "lib/sun", "lib/matlab" };', text)

【问题讨论】:

  • 如果 1 个文件中只有 1 行,那么手动替换 path_list_ 比等待 7 天获得最佳答案要高效得多。 :)

标签: regex sed replace


【解决方案1】:

根据您提供的 Python 正则表达式:

echo 'char * path_list_[1] = { "/some/random/path" };' | \
    sed -E -e 's/char \* path_list_\[1\] = \{ "[^"]*" \};/char * path_list_[2] = { "lib\/sun", "lib\/matlab" };/'

输出

char * path_list_[2] = { "lib/sun", "lib/matlab" };

或交替

echo 'static const char * path_list_[1] = { "/some/random/path" };' | \
    sed -E -e 's/static const char \* path_list_\[1\] = \{ "[^"]*" \};/static const char * path_list_[2] = { "lib\/sun", "lib\/matlab" };/'

输出

static const char * path_list_[2] = { "lib/sun", "lib/matlab" };

(这是使用 Mac OS X 中包含的 FreeBSD 类型的 sed 完成的。)

【讨论】:

    【解决方案2】:

    试试这个:

    sed -e 's/=\s*{\s*"[^"]*"\s*};/= { "lib\/foo", "lib\/bar"};/' source.c | sed -e 's/path_list_\[1\]/path_list_[2]/'
    

    【讨论】:

    • @compie:是的,sed 确实支持 char 类中的否定。我已经更新了我的答案。
    • 此解决方案匹配的行数过多。输入文件包含许多其他 C 代码。
    • @compie: 你能告诉我一些被错误替换的行吗?
    【解决方案3】:
    $ cat file
    aaaa
    char * path_list_[1] = { "/some/random/path" };
    zzzz
    
    $ sed '/char/s@1\]@2]@;s@{.*}.*$@{\"lib\/foo", "lib\/bar"}@' file
    aaaa
    char * path_list_[2] = {"lib/foo", "lib/bar"}
    zzzz
    

    【讨论】:

    • 这是一个sed oneliner...其他文本只是演示。
    • 它可以工作,但是像 struct = { "value" }; 这样的一行也被替换了。
    • 那么你应该展示更多的字符串示例和你需要解析的格式。在您的示例文本中,您没有 struct
    【解决方案4】:

    首先,找到一个不会出现在您的路径或替代品中的字符(通常# 是一个很好的初步近似值,但是...)。

    然后:

    sed 's#_.1. = {[^}]*}#_[2] = { "your/first", "and/your/second" }#'
    

    注意s之后的第一个字符是你的分隔符,它不需要是/,它只是传统的“我不需要的字符”。

    编辑:似乎 sed 不将 + 理解为“一个或多个”。请改用*(零个或多个)。

    【讨论】:

    • 它不起作用:echo 'char * path_list_[1] = { "/some/random/path };' | sed 's#_.1. = {[^}]+}#_[2] = { "your/first", "and/your/second" }#' 没有任何内容被替换。
    • Sed 确实理解+,但你应该写\+ 而不是+,或者提供-r 密钥。
    【解决方案5】:

    假设您要替换名为 path_list_ 的字符串变量,并且仅替换那些。

    sed '/path_list_/s@1\]@2]@; /path_list_.*\[.*{/s@\".*\"@\"lib\/foo", "lib\/bar"@'
    

    这仅替换以下输入的前 2 行。

    char * path_list_[1] = { "/some/random/path" };
    char * path_list_[1] = {"/some/random/path"};
    char * not_replaced[1] = { "/some/random/path" };
    char * not_replaced[1] = {"/some/random/path"};
    char * path_list_ = {"/some/random/path"};
    path_list_[1] = "/some/random/path";
    

    【讨论】:

      【解决方案6】:
      sed -e 's@char \* path_list_\[1\] = { "[^"]*" };@char * path_list_[2] = { "lib/foo", "lib/bar" };@g'
      

      【讨论】:

        【解决方案7】:
        sed -re 's/^(char \* path_list_\[)1(\] = \{ ")[^"]*(" \})\W*$/\12\2\/lib\/foo", "\/lib\/bar\3/' source.c
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-11
          • 2018-01-02
          • 2012-08-17
          • 1970-01-01
          • 2017-12-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多