【问题标题】:Using sed with regex to find and replace a string使用 sed 和正则表达式查找和替换字符串
【发布时间】:2016-08-16 22:52:52
【问题描述】:

所以我的config.fishinit.vim 中有以下字符串:

鱼:eval sh ~/.config/fish/colors/base16-monokai.dark.sh
Vim:colorscheme base16-monokai
维姆:let g:airline_theme='base16_monokai'

我有以下 shell 脚本:

#!/bin/sh

theme=$1
background=$2

if [ -z '$theme' ]; then

    echo "Please provide a theme name."

else

    if [ -z '$background' ]; then
        $background = 'dark'
    fi

    base16-builder -s $theme -t vim -b $background > ~/.config/nvim/colors/base16-$theme.vim &&
    base16-builder -s $theme -t shell -b $background > ~/.config/fish/colors/base16-$theme.$background.sh &&
    base16-builder -s $theme -t vim-airline -b $background > ~/.vim/plugged/vim-airline-themes/autoload/airline/themes/base16_$theme.vim

    sed -i -e 's/foo/eval sh ~/.config/fish/colors/base16-$theme.$background.sh/g' ~/Developer/dotfiles/config.fish
    sed -i -e 's/foo/colorscheme base16-$theme/g' ~/Developer/dotfiles/init.vim
    sed -i -e 's/foo/let g:airline_theme='base16_$theme'/g' ~/Developer/dotfiles/init.vim


fi

基本上这个想法是脚本将生成使用此builder 传递的任何主题。

我尝试过引用此documentation,但我对正则表达式不是很熟练,所以如果有人能帮我一把,我将不胜感激。

我需要做的是,一旦生成脚本sed 将查找上述字符串并将主题替换为新生成的主题。

【问题讨论】:

    标签: regex bash shell vim sed


    【解决方案1】:

    试试这个:

    sed -i "s|\(eval sh ~/\.config/fish/colors/base16-\)\([^.]*\)\.\([^.]*\)\\(.*\)|\1$theme.$background\4|
    " ~/Developer/dotfiles/config.fish
    sed -i "s/\(base16\)\([-_]\)\([a-zA-Z]*\)/\1\2$theme/g" ~/Developer/dotfiles/init.vim
    

    假设在第二个 sed 命令中主题是一个字母数字字符串。如果没有,您可以使用其他字符(例如[a-zA-Z0-9])来完成字符范围:[a-zA-Z]

    【讨论】:

      【解决方案2】:

      您可以使用以下语法替换 sed 中的某些内容:sed "s#regex#replacement#g"。因为你的字符串中有/s 和's,所以不需要转义它们是最简单的。

      有些字符需要转义才能生成正则表达式。 .$ 需要使用 \ 进行转义。替换字符串中的$ 也需要转义。

      如果你想从匹配中捕获某个部分,使用 char 类是最简单的。例如,如果您希望替换为airline_theme='$1_base16_\$theme',则eval sh ~/\.config/fish/colors/base16-([^.]+)\.dark\.sh 将是要使用的正则表达式。在这种情况下,替换中的 $1 是正则表达式中捕获的东西。

      • [^.]+ 将捕获到下一个 . 的所有内容

      我希望这可以帮助您更好地理解正则表达式!这应该足够详细,以向您展示如何编写自己的。

      【讨论】:

        【解决方案3】:

        您需要使用双引号来进行参数扩展而不是单引号。
        您需要转义单引号:'hello'\''world'

        我会为你制作一条线,并将其留作练习以修复其他线

        sed -i -e 's~\(let g:airline_theme='\''\)[^'\'']*\('\'\)'~base16_'"$theme"~' ~/Developer/dotfiles/init.vim
        

        【讨论】:

        • 嘿,谢谢@andlrc,我很感激,但问题更多在于正则表达式我需要弄清楚如何在不知道主题(monokai)的情况下找到以前的eval sh ~/.config/fish/colors/base16-monokai.dark.sh,即eval sh ~/.config/fish/colors/base16-{*}.{*}.sh,但不能不知道语法。
        【解决方案4】:

        sed 表达式字符串中s 之后的第一个字符用作模式分隔符,因此通过将/ 放在首位,您已指定 / 作为分隔符。

        另外使用单引号告诉shell不要扩展任何变量,你会想要使用双引号来代替。

        试试类似的东西

        sed -i -e "s#foo#eval sh ~/.config/fish/colors/base16-$theme.$background.sh#g" ~/Developer/dotfiles/config.fish
        

        正如您现在所说,您需要找到以前的主题字符串而不是 foo

        sed -i -e "s#eval sh \~/\.config/fish/colors/base16-.*?\..*?\.sh#eval sh ~/.config/fish/colors/base16-$theme.$background.sh#g" ~/Developer/dotfiles/config.fish
        

        【讨论】:

          猜你喜欢
          • 2012-12-13
          • 1970-01-01
          • 1970-01-01
          • 2021-05-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-01
          • 1970-01-01
          相关资源
          最近更新 更多