echo "$STRING" | iconv -t ascii//TRANSLIT | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | tr A-Z a-z |
I would add ' for compatibility with zsh
Thank you very much @gerardo-junior !
Best to replace tr A-Z a-z
at the end by tr "[:upper:]" "[:lower:]"
to support accentuated characters like É
f.i.
Best to replace
tr A-Z a-z
at the end bytr "[:upper:]" "[:lower:]"
to support accentuated characters likeÉ
f.i.
These characters are handled by iconv. I thought, were they not, they would be handled by sed replace, but at least in GNU sed 4.8 most of them belongs to a-z range.
╰─➤ echo É | iconv -t ascii//TRANSLIT
E
# not every diacritic is contained in a-z
╰─➤ echo "ā, ä, ǟ, ḑ, ē, ī, ļ, ņ, ō, ȯ, ȱ, õ, ȭ, ŗ, š, ț, ū, ž." | sed -r 's/[^a-zA-Z0-9]+/-/g' | sed -r 's/^-+\|-+$//g' | tr A-Z a-z 130 ↵
ā-ä-ǟ-ḑ-ē-ī-ļ-ņ-ō-ȯ-ȱ-õ-ȭ-ŗ-š-ț-ū-
It's good to replace multiple sed
processes with a single one using multiple -e
parameters.
It's good to use [:alnum:]
instead of [^a-zA-Z0-9]
.
It's good to use tr "[:upper:]" "[:lower:]"
instead of tr A-Z a-z
as a matter of principle for the goal of lowercasing input. To know that tr A-Z a-z
is good enough requires verifying what comes before in the pipeline, and knowing how iconv
works. That's added mental burden.
Putting it together:
iconv -t ascii//TRANSLIT | sed -E -e 's/[^[:alnum:]]+/-/g' -e 's/^-+|-+$//g' | tr '[:upper:]' '[:lower:]'
When I run
I get the expected output:
esperanca-do-voo-do-aviao
So I don't see why
sed -E 's/[~\^]+//g'
is necessary.Also, the original code handles removal of all trailing hyphens with this regex
sed -E 's/^-+|-+$//g'
In English, this regex finds one or more hyphens at the start or one or more hyphens at the end then removes all matches.
Notice that I removed the escape character (backslash) from the OR. In adding single quotes around the thing, the pipe doesn't need to be escaped and the backslash actually resulted in it being non-functional.
So this one is redundant:
sed -E 's/-$//g'
Removing all starting and trailing dashes is mandatory due to the rules on DNS names. See DNS Syntax Rules
So the more concise version that supports zsh and OSX compatibility is
Note that if keeping multiple hyphens is something desirable, this code won't work. Just add the hyphen to the allowable characters regex to keep multiple hyphens. I read something about how there cannot be hyphens in both the third and fourth position and verified that for domain names but I don't know if that applies to subdomain parts of a domain name or elsewhere. This code does not handle this.