Compiled external programs may be faster in themselves, but this is balanced against the need for the shell to spawn extra processes for them.
My usual advice is to mostly use text-processing tools like grep/sed/awk when you have to operate on large blocks of text en-masse, or if you have complex operations that the shell can't do easily. Pre-filtering lines with
grep before reading them into the shell is a good use of it, for example. But once a text string is stored in a variable, it's nearly always more efficient to use in-shell manipulations like parameter substitution. Remember the shell interpreter is also a compiled program, and its individual built-in operations are generally just as efficient at what they do as the others.
As for readability, or to be more precise comprehensibility, there is a rather large subjective component involved, and a lot of it depends on experience. I personally find shell code to be no more difficult to understand than the syntax of
sed or
awk, and it can often be easier to figure out than some of the more complex expressions of the latter.
I will admit that, given a choice between a
sed one-liner and a 10 line shell function that does the same thing, it often make sense to go with the former. But this kind of thing is not at all acceptable in my opinion:
Code:
# uggh!
var=foobarbaz
var=$( echo "$var" | sed 's/baz$//' )
echo "$var"
# yes!
var=foobarbaz
var=${var%baz}
echo "$var"
I find the in-shell version to be both cleaner and easier to read, and it's almost infinitely faster (it's hard to beat 0).
And of course, the topic at hand here is optimization, not readability. When milliseconds count,
sed it out, at least in kind of operations like the above.