minor tr(1) gotcha I encountered recently: It does NOT use regex-style "[a-z]" notation for a character class. One might do something like

$ echo 'abcd123' | tr -d '[a-c]'
d123

which does what's expected. But then put a "[" or "]" in the input:

$ echo '[abcd123]' | tr -d '[a-c]'
d123

The "[" and "]" are treated as literal characters and get deleted/translated too. You can use class-names with them though:

$ echo '[abcd123]' | tr -d '[:alpha:]'
[123]

The reason that

$ … | tr "[a-z]" "[A-Z]"

works is that the left-bracket gets translated to a left-bracket and the right-bracket gets translated to a right bracket, so you don't see an issue.

It *is* documented in man pages:

>System V has historically implemented character ranges using the syntax “[c-c]” instead of the “c-c” used by historic BSD implementations and standardized by POSIX. … if the shell script is deleting or squeezing characters as in the command “tr -d [a-z]”, the characters ‘[’ and ‘]’ will be included in the deletion or compression list which would not have happened under a historic System V implementation.

But it's easy to miss.

0

If you have a fediverse account, you can quote this note from your own instance. Search https://mastodon.bsd.cafe/users/gumnos/statuses/116029732546966332 on your instance and quote it. (Note that quoting is not supported in Mastodon.)