Adding to what's already here:
String maipulation in modern shells is better. With older sh, you have the ${var##pattern}
and ${var%%pattern}
contructs, but with bash and ksh93 (and other less-common shells) you get operators that will do string replacement (like ${var/source/replace}
).
The extglob regular expression support is also fairly handy, though not exactly new, it's usually underutilized by old-school shell programmers
[[ "$str" = @(+([a-z])?([0-9])) ]]
to match strings which are either all alphanumeric or alphanumeric ending with one number. I use that all the time in ksh88...
Then there's variable variables (var=hello; hello=hi; echo $$var
) and arrays which are large enough to actually be useful. Arrays are another of those things that old-school shell developers often underutilize, partially because of the 1024 element limit that existed in older shells - modern shells support at least 4096 elements, and most of them support associative arrays (perl calls them hashes).