![](/static/61a827a1/assets/icons/icon-96x96.png)
![](https://lemmy.ml/pictrs/image/q98XK4sKtw.png)
I did it!! It also handles the case where an external link and internal link are on the same line :D
sed -E ':l;s/(\[[^]]*\]\()([^)#]*#[^)]*\))/\1\n\2/;Te;H;g;s/\n//;s/\n.*//;x;s/.*\n//;/^https?:/!{:h;s/^([^#]*#[^)]*)(%20|\.)([^)]*\))/\1-\3/;th;s/(#[^)]*\))/\L\1/;};tl;:e;H;z;x;s/\n//;'
Here is my annotated file
# Begin loop
:l;
# Bisect first link in pattern space into pattern space and append to hold space
# Example: `text [label](file#fragment)'
# Pattern space: `file#fragment)'
# Hold space: `text [label]('
# Steps:
# 1. Strategically insert \n
# 1a. If this fails, branch out
# 2. Append to hold space (this creates two \n's. It feels weird for the
# first iteration, but that's ok)
# 3. Copy hold space to pattern space, remove first \n, then trim off
# everything past the second \n
# 4. Swap pattern/hold, and trim off everything up to and incl the last \n
s/(\[[^]]*\]\()([^)#]*#[^)]*\))/\1\n\2/;
Te;
H;
g; s/\n//; s/\n.*//;
x; s/.*\n//;
# Modify only if it is an internal link
/^https?:/! {
# Add hyphens
:h;
s/^([^#]*#[^)]*)(%20|\.)([^)]*\))/\1-\3/;
th;
# Make lowercase
s/(#[^)]*\))/\L\1/;
};
# "conditional" branch so it checks the next conditional again
tl;
# Exit: join pattern space to hold space, then move to pattern space.
# Since the loop uses H instead of h, have to make sure hold space is empty
:e;
H;
z;
x; s/\n//;
No problem. I think this is a great “final boss” question for learning sed, because it turns out it is deceptively hard!! You have to understand not only a lot about regex, but about sed to get it right. I learned a lot about sed just by tackling this problem!
It is very delicate for sure, but one part you can for sure change is at the
# Add hyphens
part. In the regex you can see(%20|\.)
. These are a list of “characters” which get converted to hyphens. For example, you could modify it to(%20|\.|\+)
and it will convert+
s to-
s as well!Still it is not perfect:
\\\\\[LINK](#LINK)
or[LINK\]\\\\](#LINK)
But for a sed-only solution this is about as good as it will get I’m afraid.
Overall I’m very happy with it. Someday I would like to make a video that goes into depth about sed, since it is tricky to learn just from the docs.