3

Is there a way, portable across POSIX operating systems and locale-aware, to switch text case from the command line--that is replacing lower case letters by upper case ones and vice versa.

Using GNU sed, I can use that:

echo 'Yes, I Know IT!' | sed -E 's/([[:upper:]]*)([[:lower:]]*)/\L\1\U\2/g'
yES, i kNOW it!

Which works nicely with accented letters:

echo Élève | sed -E 's/([[:upper:]]*)([[:lower:]]*)/\L\1\U\2/g'
éLÈVE

But since it uses the \L and \U GNU extension is not portable. And tr, on the other hand, does not properly handle accented letters on my Linux box:

echo 'Élève' | tr '[:lower:][:upper:]' '[:upper:][:lower:]'
ÉLèVE

Any solution?

migrated from serverfault.com Sep 17 '18 at 22:10

This question came from our site for system and network administrators.

  • Does your POSIX requirement exclude perl? (This is a pragmatic question, not a purist one, because I know that PCRE are not included within POSIX.) – roaima Sep 17 '18 at 22:16
  • 1
    @roaima I though about Perl, but I would have preferred a solution using only the standard utilities: pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html However, if there is no such solution, any "widely available" solution should do the trick... – Sylvain Leroux Sep 17 '18 at 22:42
4

If you'll accept perl, then this solution copied straight from Perl, using tr function to convert uppercase to lowercase and vice-versa at the same time? will work for you:

echo 'Hello Élève. It is beautiful!' |
    perl -Mopen=locale -Mutf8 -pe 's/([[:upper:]])|([[:lower:]])/defined $1 ? lc $1 : uc $2/eg'

hELLO éLÈVE. iT IS BEAUTIFUL!

I also wondered about using something like ( gsed ... || tr ... ) so that on systems with GNU's gsed it would take priority, but on other systems where tr was probably not GNU that would execute instead. (Non-GNU POSIX tr apparently handles multi-byte characters correctly.)

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.