3

I need to extract an ID from the output of another command. Currently my extracting command looks like:

someID=$(command | grep -oP '(?:^Successfully\sbuilt\s)([\da-z]{12}$)' | grep -oP '([a-z\d]{12})')

Example command output:

 ---> Using cache
 ---> 9b4624927fa6
Successfully built 9b4624927fa6

Expected result:

9b4624927fa6

ID extracted from line

Successfully built 9b4624927fa6

How could I merge those two grep statements into single one?

4
  • I don't really understand your question. Your command seems to do exactly what you want.
    – Sjoerd
    Commented Apr 11, 2019 at 8:12
  • 6
    If you are building a docker image, you can give it a name with the --tag option. That way, you can supply the name instead of having to parse it from the output. Also, --quiet supresses all output except for the image ID.
    – Sjoerd
    Commented Apr 11, 2019 at 8:13
  • @Sjoerd Yes, but they want to combine the two grep calls into a single command.
    – Kusalananda
    Commented Apr 11, 2019 at 8:16
  • @Sjoerd oh thanks for suggestion, will definitely try it, I need that id exactly for this reason, want to build simple automated pipeline for docker containers Commented Apr 11, 2019 at 8:17

2 Answers 2

10

A slight modification of your first grep works for me:

$ grep -oP '^Successfully\sbuilt\s\K[\da-z]{12}$' example-output
9b4624927fa6

\K in PCRE resets the match start:

The escape sequence \K causes any previously matched characters not to be included in the final matched sequence.

It's similar to a zero-width positive look-behind assertion (?<=Successfully...).

3
  • 4
    \K is not a look behind assertion, it just sets the start of the matched text here reported by -o. Compare echo aaaaa | grep -Po 'a\K.' with echo aaaaa | grep -Po '(?<=a).' (this time using a look-behind assertion). Commented Apr 11, 2019 at 16:17
  • 1
    @StéphaneChazelas: To be fair, perlre describes it in the same list item as positive look-behind assertions, with language and typography that strongly suggests thinking of one as a variant of the other (even though that can't be the case at a technical level). Commented Apr 11, 2019 at 22:48
  • 1
    @HenningMakholm, yes, it's unfortunate. The pcrepattern man page does not make that confusion. It's true \K can often be used in place or positive look behind assertions. Commented Apr 11, 2019 at 22:58
7

To get the hexadecimal number at the end of a line that starts with Successfully built, I would probably use sed:

sed -n -E 's/^Successfully built ([[:xdigit:]]+)$/\1/p'

This replaces the matching line with the hash and prints it (and no other line).

Or awk:

awk '/^Successfully built [[:xdigit:]]+$/ { print $NF }'

This prints the last whitespace-delimited field of each line matching the regular expression.

In both regular expressions, the [[:xdigit:]]+ expression will match a non-empty string of hexadecimal digits.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .