Regex Bash sed将字符串与上面和下面的换行符匹配

Regex Bash sed将字符串与上面和下面的换行符匹配,regex,bash,sed,Regex,Bash,Sed,这是一个文本文件的摘录 http_server = Server( uuid = "9a44b850-c54f-11e3-9c1a-0800200c9a66", ) # https_server = Server( # uuid = "0c9cb0c0-c55e-11e3-9c1a-0800200c9a66", # ) 我想使用sed(或类似的东西)从文件中提取:“0c9cb0c0-c55e-11e3-9c1a-0800200c9a66” 我尝试过cat server.con

这是一个文本文件的摘录

http_server = Server(
    uuid = "9a44b850-c54f-11e3-9c1a-0800200c9a66",
)

# https_server = Server(
#     uuid = "0c9cb0c0-c55e-11e3-9c1a-0800200c9a66",
# )
我想使用sed(或类似的东西)从文件中提取:“0c9cb0c0-c55e-11e3-9c1a-0800200c9a66”

我尝试过
cat server.conf | sed-n的/*uuid=“\(.*)”,/\1/p'
,但它同时提供了两个uuid。当我输入诸如
\n
之类的新行时,sed根本不起作用

uuid的唯一标记是
https\u服务器
,正则表达式必须确保uuid位于
https\u服务器

内,请尝试以下操作:

cat server.conf | sed -n -e '/https_server/{N;p}' | sed -n -e 's/.*uuid = "\([^ ]*\)",/\1/p'
或者只调用一次sed:

cat server.conf | sed -n -e '/https_server/{N;s/.*uuid = "\([^ ]*\)",/\1/p}'
或者,如果在块内的https_服务器和uuid行之间可能存在多条空行:

cat server.conf | sed -n -e '/https_server/,/uuid/p' | sed -n -e 's/.*uuid = "\([^ ]*\)",/\1/p'

为确保
uuid
位于
https\u服务器
内,您可以跳过所有行,直到到达该字符串:

cat server.conf | sed -n '/https_server/,//{//!p}' | sed -n 's/.*uuid = "\(.*\)",/\1/p'

这一行查找可能被注释掉的
https\u服务器
行,然后在下一个右括号之前的块中提取任何
uuid

sed -n '/^#* *https_server *=.*(/,/)/!d;/^#* *uuid *= *"/!d;s///;s/",//p' searver.conf
这避免了重复调用和愚蠢的多次
sed
调用

/regex/,/regex/
选择一个区域。动作
!d
只需丢弃此区域之外的任何行

/^ *uuid *= *"/
选择区域中与此图案匹配的任何线。再一次,
!d
丢弃任何未选中的行

s///
删除以前匹配的图案

最后,

s/",//
删除字符串末尾的引号和逗号

一些
sed
方言可能希望您将文字括号反斜杠。

这可能适合您(GNU-sed):

如果
uuid
不在下一行,而是在下一行,请使用:

sed -rn '/https_server/{:a;n;/\)\s*$/b;s/.*uuid = "([^"]*)".*/\1/p;Ta;q}' server.conf

一个问题是文件可能有或没有
#
。但是,我希望它通过
https\u服务器
来区分。我更新了问题,以澄清
https\u服务器
边界很重要。因此,如果第二个https\u服务器前面没有#和uuid,根据您的示例,如何区分这两个?我想,在这种情况下,您仍然只想找到第一个uuid,对吗?不,我想找到https_服务器块中的uuid。
sed -rn '/https_server/{:a;n;/\)\s*$/b;s/.*uuid = "([^"]*)".*/\1/p;Ta;q}' server.conf