微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sed查找字符串,打印所有内容,直到下一个模式

如何解决sed查找字符串,打印所有内容,直到下一个模式

我们继承了以下情形。

具有“每个服务主机数”的文件通过管道传输到sed。

根据服务名称,将返回主机列表。

使用的命令:

/bin/sh -c 'cat file.txt | sed -n "/main-service]/,/\\[/{/\\[/!p;}"'

操作系统:Ubuntu 14 16 18 20

在旅途中,我们发现sed返回的主机数量超出了我们的预期。

我试图在不修改sed('/main-service]/')的第一部分的情况下解决此“贪婪”行为,

对此的解决方法可以是:'/\[main-service]/',但我不知道它到底能阻止什么(此sed在很多地方都使用过),所以我试图避免进行此编辑。 >

文件示例(Sed输入):

[main-service]
hosta
hostb
hostc

[that-main-service]
hostd
hoste


[other-main-service]
hostf
hostg

在下面的示例中,我们正在“ main-service”下查找所有主机

/bin/sh -c 'cat file.txt | sed -n "/main-service]/,/\\[/{/\\[/!p;}"'

但是,输出结果不是我们期望的

hosta
hostb
hostc

hostf
hostg

我不知道创建者对sed语法的确切含义,但是我想实现的是:

if service name == '/main-service]/' #find only the line that matches

take all the text until '\n\['

此处示例:

https://sed.js.org/?gist=0a90e4d015d02b820072e6cf837e6204

预期输出为:

hosta
hostb
hostc

任何帮助将不胜感激。

谢谢。

解决方法

您可以使用显示的示例尝试在awk中进行关注。

awk '/^\[/ && found{exit} /^\[main-service\]/{found=1;next} found && NF' Input_file

输出如下。

hosta
hostb
hostc

说明: 添加以上详细说明。

awk '                 ##Starting awk program from here.
/^\[/ && found{       ##Checking condition if line starts from [ and found is NOT NULL then do following.
  exit                ##exit from this program,no need to read whole Input_file.
}
/^\[main-service\]/{  ##Checking condition if line starts from [ main-service] then do following.
  found=1             ##Setting found to 1 here.
  next                ##next will skip all further statements from here.
}
found && NF           ##Checking condition if found is SET and NF is NOT NULL then print that line.
' Input_file          ##Mentioning Input_file name here.
,
sed -n '/\[main-service]/,/^$/{//!p}'

最合适,但您提到您不愿意使用\[

因此,您可以使用

退出第一个此类比赛
sed -n '/main-service]/,/^$/{//!p; /^$/q}'

此外,您可以直接将文件名传递给sed,而无需使用cat,而且我不确定为什么您使用/bin/sh -c而不是调用{{1} }直接。

,

这可能对您有用(GNU sed):

/bin/sh -c 'cat file | sed -n "/main-service]/{n;:a;p;n;/\\[/q;ba}"'

这使用相同的正则表达式,但操纵程序流。

原始sed命令可能附加了超出预期的附加内容,因为打印的停止点取决于是否存在另一个节或文件结束条件。

,

重新考虑您为范围选择的定界符可能会有所帮助。由于][括号在同一行,因此逻辑混乱。

使用节标题的完整模式来匹配范围/^\[main-service]/的开始,并使用空行来匹配范围/^$/的结束

sed -n  '/^\[main-service]/,/^$/p' services.txt | sed '1d;$d;'
  • -n选项可禁止自动打印。
  • p命令来打印范围的行

由于结果包含标题和空白行,因此我们将结果传递到第二条命令中以删除第一行和最后一行sed '1d;$d;'

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。