So I'm currently using this one liner to get the latest release version of docker-compose.

curl --silent "https://api.github.com/repos/docker/compose/releases/latest" | grep "tag_name" | sed -E 's/.*"([^"]+)".*/\1/'

Now I am very interested in the sed statement specified. Can anyone help me understand it better?

sed -E 's/.*"([^"]+)".*/\1/'

Output of command without the sed statement: "tag_name": "1.22.0",

Output of command with the sed statement: 1.22.0

  • which sed? my gnu sed, does not have -E – ctrl-alt-delor Jul 31 '18 at 9:16
  • Which parts of regex are you struggling with? What do you understand so far? – ctrl-alt-delor Jul 31 '18 at 9:17
  • @ctrl-alt-delor GNU sed has supported -E (a la BSD) for a while now (4.2 in 2009) even though it was initially undocumented (documented in 4.3 2017). -E is going to make it to the POSIX standard. GNU sed had -r initially for that. – Stéphane Chazelas Jul 31 '18 at 9:19
  • It may make more sense to use a JSON parsing tool here. Like jq -r .tag_name. – Stéphane Chazelas Jul 31 '18 at 9:20
  • Yes jq will be more stable, as json can be formatted onto one line etc etc etc. – ctrl-alt-delor Jul 31 '18 at 9:24

sed -E 's/.*"([^"]+)".*/\1/

  • -E: sed will use Extended Regex
  • 's': to substitute value.
  • /: the separator of pattern and replacement that will be use.
  • .*"([^"]+)".*: the best way I know to explain regex is a graph:
    regex explantation
    Basically it matches every line that have two block of quotes and put the second one (without the quotes) inside group one.
  • /: separator between your regexp and your replacement
  • \1: replace your original line with the group number 1 : 1.22.0 in this case.
  • /: last separator without option after it so it will replace only once a line.

Hope this is explain well enough.


I don't know what you know about sed. in sed you may found:

sed - stream editor for filtering and transforming text


-E, -r, --regexp-extended use extended regular expressions in the script (for portability use POSIX -E).

in sed you could define, let me say, word pattern between parantheses and you could catch them with \No. in your question, let me write as below:

echo '"tag_name": "1.22.0"' | sed -E 's/"([a-z]+\_[a-z]+)": "([0-9\.]+)"/\2/'
  • -E use extended regular expressions
  • 's/Part1/Part2/ the main structure
  • " regex pattern start with "
  • ([a-z]+\_[a-z]+) first word Pattern containds two part of chars joied with _
  • ": " after that these sequence symbols would occured
  • ([0-9\.]+) the second word Pattern contains as many digit with .
  • " pattenr end with it.
  • \2 now you call the second word Pattern

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.