Convert all text from uppercase to lowercase and vice versa?

Here is a straight way in sed:

$ echo qWeRtY | sed -e 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/'
QwErTy

or a shorter way with GNU sed, working with any character for which a lowercase<->uppercase conversion exists in your locale:

$ echo qWeRtY | sed -E 's/([[:lower:]])|([[:upper:]])/\U\1\L\2/g'
QwErTy

if you can use another tools, like:

perl (limited to ASCII letters):

$ echo qWeRtY | perl -pe 'y/[a-z][A-Z]/[A-Z][a-z]/'
QwErTy

perl (more generally):

$ echo 'αΒγ' | perl -Mopen=locale -pe 's/(\p{Ll})|(\p{Lu})/uc($1).lc($2)/ge'
ΑβΓ

POSIXly, that can't be done with sed except by providing the complete set of letters you want to transliterate as @cuonglm has shown.

It could be done with tr though, and that's what tr is for (transliterate):

tr '[:lower:][:upper:]' '[:upper:][:lower:]'

However, on Linux, it's got limitations. Of the 3 tr implementations commonly found on Linux-based systems:

  • with GNU tr, that only works for single-byte character sets. For instance, on Stéphane Chazelas in UTF-8 locales, that gives sTéPHANE cHAZELAS instead of sTÉPHANE cHAZELAS. That's a known limitation of GNU tr.
  • with tr from the heirloom toolchest, that doesn't work (you get stéphane chazelas).
  • That's not the kind of thing busybox tr will do.

On FreeBSD that works OK though. You'd expect it to work OK in certified Unix systems as well.


The bash shell has a dedicated operator for that:

in=AbCdE
out=${in~~}

With zsh -o extendedglob:

out=${in//(#b)(([[:lower:]])|([[:upper:]]))/${(U)match[2]}${(L)match[3]}}

If your main objective is to convert a file from lowerclass to upperclass, why dont you use tr and STDOUT to convert your file:

$cat FILENAME | tr a-z A-Z > FILENAME2

Where FILENAME is your original file. Where FILENAME2 is your converted output file.

Tags:

Sed