So far, this is just a short selection of items. I plan to convert this into a more elaborate form and provide examples sooner or later.
General
Bash has now many things built-in, that once required calling external commands. Most notably:
- The testing of conditions used
[...]
which is just an alias for the programtest
. Just using[[...]]
instead lets Bash evaluate the condition itself. This doesn't matter for singleif
statements, but complex scripts with loops experience a huge speed-up. - Simple calculation and string handling can be done by
$(( 1 + I ))
(instead ofexpr 1 + $I
) and${DIR/foo/bar}
instead of callingsed
. - Regular Expressions are build in (use
[[...]]
)
Small bits and pieces
CamelCase
For an auto-generated TeX file, I want to automatically generate a CamelCase
expression
from filenames containing dashs and underlines.
Many suggestions on the internet propose using sed
or other secondary tools,
but I tried to get it with Bash Buildins.
Bash has the parameter expansions
${parameter^pattern}
and ${parameter,pattern}
that convert the first matched character to upper or lower case.
By setting the pattern to *
or ?
, the first letter of the variable $parameter
is converted:
$ STR='abc def'
$ echo ${STR^?}
Abc def
$ echo ${STR^*}
Abc def
$ echo ${STR^^*}
ABC DEF
There are variants with two ^^
or ,,
that convert every occurence of a matched pattern.
But how to convert only the first letter of every word?
The solution is to use an array and apply the conversion to each element:
$ ARR=( $STR )
$ echo ${ARR[*]^*}
Abc Def
Back to the initial challenge: convert a string like my-filename_variant1
.
The approach is to convert the special characters to spaces
and then tokenize the character string at word boundaries to an array.
$ TMP='my-filename_variant1'
$ TMP=${TMP//-/ } # convert all '-' to spaces
$ TMP=${TMP//_/ } # convert all '_' to spaces
$ TMP=( $TMP ) # tokeninze words to array
$ TMP=${TMP[*]^*} # upper-case all words
$ TMP=${TMP// /} # remove spaces
$ echo $TMP
MyFilenameVariant1
There are probably more elegant ways with sed
.
I'm not sure, if it could be solved with Bash's regular expressions.
And finally, I'm also not sure if this is still more efficient than a forked sed
,
but it is amazing what can be done with Bash alone.
Source: solved this problem with the creative help of Stackoverflow.