Using Raku (formerly known as Perl_6)
Sample Input:
~$ cat file The RIVER dee in Aberdeen can be cold, so i shiver when i swim. Scotland is STILL beaUtIful though. eveN when it RAINS? "YES! of course", is the obvious answer.
Upper Case:
~$ raku -ne '.uc.put;' file THE RIVER DEE IN ABERDEEN CAN BE COLD, SO I SHIVER WHEN I SWIM. SCOTLAND IS STILL BEAUTIFUL THOUGH. EVEN WHEN IT RAINS? "YES! OF COURSE", IS THE OBVIOUS ANSWER.
Lower Case:
~$ raku -ne '.lc.put;' file the river dee in aberdeen can be cold, so i shiver when i swim. scotland is still beautiful though. even when it rains? "yes! of course", is the obvious answer.
Proper Case, a.k.a. "Title Case Lower Case" (per string: uppercase the first letter and lowercase all others), or "Wordcase" (same but works on words and so does the heavy-lifting for you):
#NOTE: `tclc` code below does not capitalize words that starts with punctuation, # [useful for "free-standing" bracketed markdown text] ~$ raku -ne 'put .words.map: *.tclc.join(" ");' file The River Dee In Aberdeen Can Be Cold, So I Shiver When I Swim. Scotland Is Still Beautiful Though. Even When It Rains? "yes! Of Course", Is The Obvious Answer. #NOTE: `wordcase` function can take a list of proper_names (see final example). ~$ raku -ne '.wordcase.put;' file The River Dee In Aberdeen Can Be Cold, So I Shiver When I Swim. Scotland Is Still Beautiful Though. Even When It Rains? "Yes! Of Course", Is The Obvious Answer.
Sentence Case (accomplished with split or subst):
~$ raku -e 'my @a = [Z~] <. ! ? . ! ?>, " \n\n\n".comb; my @b = slurp.split(@a, :p); \ put join "", [Z~] @b[0,2,4,6 ... Inf]>>.tclc, @b[1,3,5,7 ... Inf].map: *.value;' file The river dee in aberdeen can be cold, so i shiver when i swim. Scotland is still beautiful though. Even when it rains? "yes! Of course", is the obvious answer. #OR (more simply, also capitalizes ` I `) ~$ raku -e 'slurp.tclc.subst(:global, / <[.!?]> \s <( <:P>? <:L> | \si\s )> /, {$/.uc // ""} ).put;' dee.txt The river dee in aberdeen can be cold, so I shiver when I swim. Scotland is still beautiful though. Even when it rains? "Yes! Of course", is the obvious answer.
Sentence Case with Proper Names Capitalized (accomplished with wordcase and subst):
~$ raku -e 'my @txt = slurp.tclc.wordcase(:filter(&tc), :where({ .match(:ignorecase, :global, / river | dee | aberdeen | scotland /) })); \ my @sep = [Z~] <. ! ? . ! ?>, " \n\n\n".comb; \ for @sep -> $sep { @txt.=subst(:global, / $sep <( <:P>? <:L> | [\s i \s] )> /, {$/.uc // ""} ); }; \ put @txt;' file The River Dee in Aberdeen can be cold, so I shiver when I swim. Scotland is still beautiful though. Even when it rains? "Yes! Of course", is the obvious answer. #OR (more simply) ~$ raku -e 'my @proper = <river dee aberdeen scotland>; \ my @txt = slurp.tclc.wordcase(:filter(&tc), :where({ .match(:ignorecase, :global, / @proper /) })); \ @txt.=subst(:global, / <[.!?]> \s <( <:P>? <:L> | \si\s )> /, {$/.uc // ""} ); \ put @txt;' dee.txt The River Dee in Aberdeen can be cold, so I shiver when I swim. Scotland is still beautiful though. Even when it rains? "Yes! Of course", is the obvious answer.
Raku is a programming language in the Perl family. "Casing"-methods include lc, uc, tc, tclc, and wordcase. Regex matching/substitution parameters (a.k.a. adverbs) include :ignorecase and :samecase. Various combinations of these methods/adverbs can give you a nice "Sentence Case" return at the bottom.
Explaining just the final example, the file is slurp read-in-all-at-once, converted to tclc and then wordcase takes a @proper array of matches that get capitalized. Then a substution is performed where <[.!?]> \s sentence terminating characters followed by whitespace are located, and the first <:L> (Unicode letter) character following gets converted to uc uppercase (note the <:P>? <:L> allowing for initial punctuation). Lowercase "i" (a.k.a. regex [\s i \s]) is also converted to uppercase, for good measure.
[Of course, the final example above is just a start. Caveats: only three sentence terminators are handled, and "proper" names get individually capitalized, so that e.g. "River" is capitalized whether-or-not it is followed by "Dee". Final thanks to @kes for the text (via @Stéphane_Chazelas)].
http://raku.org