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?

  • I don't really understand your question. Your command seems to do exactly what you want. – Sjoerd Apr 11 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 Apr 11 at 8:13
  • @Sjoerd Yes, but they want to combine the two grep calls into a single command. – Kusalananda Apr 11 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 – stetoc Apr 11 at 8:17
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...).

  • 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). – Stéphane Chazelas Apr 11 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). – Henning Makholm Apr 11 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. – Stéphane Chazelas Apr 11 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.