首页 文章

sed正则表达式不符合预期

提问于
浏览
2

我试图用sed操纵yum repofile并且它没有按预期工作 . 该文件看起来像这样:

[repo id]
name = value
name = value
[repo id]
name = value
name = value

这可能不是最好的方法,但我仍然想知道为什么它不起作用......

首先,我将repo文件转换为一个大字符串:

sed ':a;N;$!ba;s/\n/:::/g' $repofile |

然后, and this is the part that isn't working ,我想匹配我正在寻找的特定仓库并修剪文件的其余部分 . 我这样做是通过匹配开头[后跟包含正确repo id的字符串 . 然后我想匹配其他所有内容,直到下一个开头[在文件中:

sed "s/^.*\(\[${repoid}\].*\[\).*/\1/" >~/trimed_repo

然后我将新行重新放入并继续使用awk进行修改 .

sed 's/:::/\n/g' ~/trimed_repo >~/expanded_repo

我遇到的问题是我的正则表达式似乎跳过了所有下一个开头[在与$ repoid配对的文件中,并且只匹配文件中的最后一个开头 .

我尝试使用“懒惰量词”,但它完全阻止了正则表达式的匹配 . 像这样:

sed "s/^.*\(\[${repoid}\].*?\[\).*/\1/" >~/trimed_repo

像这样:

sed "s/^.*\(\[${repoid}\](.*?)\[\).*/\1/" >~/trimed_repo

answer*

所以在评论中有一些帮助我做了这个工作:

sed "s/^.*\(\[${repoid}\][^[]*\)\[.*/\1/" >~/trimed_repo

我的教训是,我应该做的就是说匹配所有不是开口的东西[直到找到一个开口[并且这将防止不必要的行为] .

有人可以解释为什么这两个选项的行为在这两个实例中有所不同吗? . *与第一个实例中的文件末尾不匹配 . 它在下一个指定选项处停止 . 但在第二种情况下,直到最后一次匹配才停止 .

我指的是我原来的破碎的例子:

sed "s/^.*\(\[${repoid}\].*\[\).*/\1/" >~/trimed_repo

2 回答

  • 2
    $ cat file
    [foo]
    name = 3
    name = 17
    [bar]
    name = 24
    name = 5
    
    $ awk -v id="foo" '/\[/{f=index($0,"["id"]")} f' file
    [foo]
    name = 3
    name = 17
    
    $ awk -v id="bar" '/\[/{f=index($0,"["id"]")} f' file
    [bar]
    name = 24
    name = 5
    

    上面只是在找到包含 [foo] 的行时设置一个标志(找到 f ),并在找到包含 [ 的下一行时将其清除 . 设置 f 时,将打印该行 .

    另请注意,与任何可能的sed解决方案不同,上述内容将不受搜索变量中的RE元字符或分隔符(例如 ., ?, *, +, /, (, etc. )的影响,因为它正在查找STRING而不是正则表达式 .

  • 0

    您可以使用范围从repo文件中提取匹配的部分 .

    sed -ne "/\[${repoid}\]/,/\[/{/\[${repoid}\]/p;/\[/!p}" $repofile > ~/trimed_repo
    

相关问题