Trix & Graphix

Strings in BASH

This post is to show some really nice features I have just found regarding the management of strings in Bash scripts. How have I been abled to live without this? :-)


Strings index
An array may be splitted using indexes. The sitanxis is something like ${variable:indx1:elemensts}, where inx1 is the first element on the substring you want to get (the first element is numbered 0, as in C), and elements in the number of elements you want to remain. Maybe it's easier to understand with some few examples:
var="asdf1234"

echo ${var:0}
asdf1234

echo ${var:4}
1234

echo ${var:4:1}
1

echo ${var:4:2}
12

Note that ${var:0} is equivalent to ${var}. A really interesting feature is that you may index from the right
var="asdf1234"
echo ${var: -2:2}
34
Note the blank space before the minus sign!!!


Replacing elements (regular expresions-like)
Another interesting feature is that you can use Bash to replace some elements of the string. This is a thing that people use to do with sed or awk. Nevertheless for easy tasks the direct form using Bask I'm going to explain may be useful. The sytanxis is ${variable/substringToBeReplaced/stringReplacing/}. Let's see some exmamples:

var=123ASDF123

echo ${var/123/XY}
XYASDF123

echo ${var//123/XY}
XYASDFXY

echo ${var/23}
1ASDF123
As you can see the sintaxis is similar to awk. By default, only the first time that the substring is found from the left it is replaced. Using "//" you can force to replace all the instances of the substring in the main string. Finally, if only one string is specified, it's simply removed (replaced by a null string).

Finally, if you want to replace, but beginning from the right, "%" has to be appended:

var=123ASDF123

echo ${var/#123/XY}
XYASDF123

echo ${var/%123/XY}
123ASDFXY

Note that the simbol "#" means "reading from the left". In general it is not necesary as this is the default behaviour.

Just two more examples. In order to get the name and the extension of a file:

var=name.ext

echo "The filename is ${var/%.*}"
The filename is name

echo "The extension is ${var/#*.}"
The extension is ext

Here you can see that "*" can mean the beginning as well as the end of the string.

I hope it may be useful for you :-).