Goal: replace ![alttext](url.png) with <img src="url.png" alt="alttext">.

The ! and (...) parts work fine, it's the [...] part that I can't get to work.

As a simple example, I want to match the input a [test] b. This is the command I use:

echo 'a [test] b' | sed 's/\[[^\]]*\]/x/'

It doesn't work. When I replace the square brackets with angle brackets, it works just fine:

echo 'a <test> b' | sed 's/<[^>]*>/x/'

Why does sed not understand the same regex but with escaped square brackets? It works fine in other tools such as Python.

  • It's a complex task to parse markdown. Here's the commonmark spec for reference. – glenn jackman Feb 20 '19 at 15:15
  • @glennjackman Thanks for the pointer, but I'm not trying to create a complete markdown parser. I just wanted a small shell script which replaces h1-h3, links, images, bold, italics, and paragraphs. That's just a few sed rules and makes a webpage readable so someone can semi-preview it without having to deploy it to the markdown-based CMS system. – Luc Feb 20 '19 at 16:40
  • IMO, it would be easier to just use a markdown tool to compile the markdown text into html, instead of rolling your own semi-solution. – glenn jackman Feb 20 '19 at 18:06

Within the character class definition ] is taken literally when directly following the ^. So don't escape this. Also you are missing a quantifier like +, to say "one or more characters" or * to say "zero or more characters". Furthermore there is one sed too many in your command line.

$ echo 'a [test] b' | sed 's/\[[^]]\+\]/x/'
a x b

(\+ being a GNU extension (now also supported by a few other implementations), the standard equivalent is \{1,\})

or more readable:

$ echo 'a [test] b' | sed -E 's:\[[^]]+\]:x:'
a x b

(-E being a BSD extension, now also supported by GNU sed and some other implementations; use -r in older versions of GNU sed).

| improve this answer | |
  • Ugh, the issue with hastily written questions when others are waiting for me to go to lunch: I only have one sed in the real command and the missing * is a typo as well. I'll edit the question to not confuse future readers, you might want to edit the answer. Not escaping the ^] indeed works, thanks finswimmer! – Luc Feb 20 '19 at 12:29

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.