我试图用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 回答
上面只是在找到包含
[foo]
的行时设置一个标志(找到f
),并在找到包含[
的下一行时将其清除 . 设置f
时,将打印该行 .另请注意,与任何可能的sed解决方案不同,上述内容将不受搜索变量中的RE元字符或分隔符(例如
., ?, *, +, /, (, etc.
)的影响,因为它正在查找STRING而不是正则表达式 .您可以使用范围从repo文件中提取匹配的部分 .