Bash sed匹配一个字符串,上面和下面有换行符

时间:2014-06-09 11:01:43

标签: 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.conf | sed -n 's/.*uuid = "\(.*\)",/\1/p',但它给了我两个uuids。当我输入像\n这样的换行符时,sed根本不起作用。

uuid的唯一标记为https_server,正则表达式必须确保uuid位于https_server内。

4 个答案:

答案 0 :(得分:1)

请改为尝试:

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_server和uuid行之间可能存在多个空行:

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

答案 1 :(得分:0)

为了确保uuid位于https_server内,您可以跳过所有行,直到找到该字符串:

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

答案 2 :(得分:0)

这一行查找可能已注释掉的https_server行,然后在下一个右括号之前的块中提取任何uuid

sed -n '/^#* *https_server *=.*(/,/)/!d;/^#* *uuid *= *"/!d;s///;s/",//p' searver.conf

这可以避免useless use of cat和愚蠢的多个sed调用。

/regex/,/regex/

选择一个地区。行动!d只会丢弃此区域以外的所有行。

/^ *uuid *= *"/

选择与此模式匹配的区域中的任何行。同样,!d会丢弃任何未选中的行。

s///

删除先前匹配的模式。

最后,

s/",//

删除字符串末尾的引号和逗号。

某些sed方言可能会要求您反斜杠字面括号。

答案 3 :(得分:0)

这可能适合你(GNU sed):

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

如果uuid不在下一行,而是在其他一行后面,请使用:

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