我正在尝试用sed操纵yum repofile并且它没有按预期工作。该文件看起来像这样:
[repo id]
name = value
name = value
[repo id]
name = value
name = value
这可能不是最好的方法,但我仍然想知道它为什么不起作用......
首先,我将repo文件转换为一个大字符串:
sed ':a;N;$!ba;s/\n/:::/g' $repofile |
然后,这是不起作用的部分,我想匹配我正在寻找的特定仓库并修剪文件的其余部分。我这样做是通过匹配开头[后跟包含正确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
答案*
所以在评论中有一些帮助我做了这个有用的工作:
sed "s/^.*\(\[${repoid}\][^[]*\)\[.*/\1/" >~/trimed_repo
我的教训是,我应该说的是匹配所有不是开口的东西[直到找到一个开口[并且这将防止不必要的行为。
有人可以解释为什么这两个选项的行为在这两个实例中有所不同吗? 。*与第一个实例中的文件末尾不匹配。它在下一个指定选项处停止。但在第二种情况下,它不会停止直到最后一次匹配。
我指的是我原来的,破碎的例子:
sed "s/^.*\(\[${repoid}\].*\[\).*/\1/" >~/trimed_repo
答案 0 :(得分: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
以上只是在找到包含f
的行时设置了一个标记(找到[foo]
),并在找到包含[
的下一行时将其清除。设置f
时,会打印该行。
另请注意,与任何可能的sed解决方案不同,上述内容不会受到搜索变量中的RE元字符或分隔符(例如., ?, *, +, /, (, etc.
)的影响,因为它正在查找STRING而不是正则表达式。
答案 1 :(得分:0)
您可以使用范围从回购文件中提取匹配的部分。
sed -ne "/\[${repoid}\]/,/\[/{/\[${repoid}\]/p;/\[/!p}" $repofile > ~/trimed_repo