简体   繁体   中英

Bash sed match a string with newlines above and below

Here's an excerpt of a text file.

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

# https_server = Server(
#     uuid = "0c9cb0c0-c55e-11e3-9c1a-0800200c9a66",
# )

I want to use sed (or something similar) to extract the: "0c9cb0c0-c55e-11e3-9c1a-0800200c9a66" out of the file.

I've tried cat server.conf | sed -n 's/.*uuid = "\\(.*\\)",/\\1/p' cat server.conf | sed -n 's/.*uuid = "\\(.*\\)",/\\1/p' but it gives me both uuids. When I put in newlines like \\n the sed doesn't work at all.

The unique marker for the uuid is https_server , the regex must make sure the uuid was inside the https_server .

Try this instead:

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

Or this invoking sed once only:

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

Or if there is chance of multiple empty lines between the https_server and uuid line inside the block:

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

为了确保uuidhttps_server内部,您可以跳过所有行,直到到达该字符串:

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

This one looks for a https_server line which is possibly commented out, then extracts any uuid in the block which follows before the next closing parenthesis.

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

This avoids the useless use of cat and the silly multiple sed invocations.

/regex/,/regex/

selects a region. The action !d simply discards any lines outside of this region.

/^ *uuid *= *"/

selects any line in the region matching this pattern. Again, !d discards any line which is not selected.

s///

deletes the previously matched pattern.

Finally,

s/",//

removes the quote and the comma at the end of the string.

Some sed dialects might want you to backslash the literal parentheses.

This might work for you (GNU sed):

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

If the uuid is not on the next line but some other following line, use:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM