Bob van Luijt
Bob van Luijt

Reputation: 7598

How to make sed (using bash) stop on a line break?

I'm using the following sed command to get a variable from a Docker-compose log file:

sudo cat $(docker inspect --format='{{.LogPath}}' xxxxx) | grep -s TOKEN|sed 's/.*TOKEN=//'

This works well, however, it returns:

57ac8392-1ecc-4e17-9350-c9c866ac832b\n","stream":"stderr","time":"2018-12-16T19:55:54.032838023Z"}

The TOKEN is indeed: 57ac8392-1ecc-4e17-9350-c9c866ac832b. But I'm not sure how to break it after the line-break (\n) to only include the UUID.

Upvotes: 1

Views: 79

Answers (1)

cody
cody

Reputation: 11157

To achieve what you want with sed, you would need to capture the token in the pattern and use a backreference to it as the replacement:

$ cat data
TOKEN=57ac8392-1ecc-4e17-9350-c9c866ac832b\n","stream":"stderr","time":"2018-12-16T19:55:54.032838023Z"}

$ cat data | sed -e 's/.*TOKEN=\([-a-f0-9]\+\)\\n.*/\1/'
57ac8392-1ecc-4e17-9350-c9c866ac832b

Are you using GNU grep? If so, you can target the token a little more simply with it alone as follows:

$ grep -sPo '(?<=TOKEN=)[-a-f0-9]+' < data
57ac8392-1ecc-4e17-9350-c9c866ac832b

Explained:

In GNU grep, -P interprets the given pattern as a PCRE, which enables features that are unavailable in the traditional POSIX regular expression language. One of these is "positive lookbehind", represented by (?<=...), that essentially tells the regex engine to step backwards and look to see if the text inside the lookbehind can be matched there, but not actually match it. This allows you to sort of "anchor" matches with a given string but not capture them.

The -o flag to grep simply tells it to only print the matching part of a given input.

When combined, these two flags allow us to use TOKEN= in the pattern to anchor the match but only print the true token data.

Upvotes: 1

Related Questions