If you are a standard programmer, utilizing bash for scripting may seem limiting sometimes, however for specific tasks, bash can be extremely productive. It turns out, a few of the limits of bash are truly limits of older shells as well as people code to that to be compatible. Still other perceived problems are since a few of the advanced functions in bash are arcane or confusing.
Strings are a great example. You don’t believe of bash as a string manipulation language, however it has lots of powerful methods to manage strings. In fact, it may have as well lots of ways, considering that the performance winds up in a lot more than one place. Of course, you can likewise phone call out to programs, as well as often it is just much easier to make a contact us to an awk or Python script to do the heavy lifting.
But let’s stick with bash-isms for managing strings. Obviously, you can put a string in an atmosphere variable as well as pull it back out. I am going to presume you understand exactly how string interpolation as well as pricing quote works. In other words, this must make sense:
1
echo “Your path is $PATH as well as the present directory is ${PWD}”
The long as well as the Short
Suppose you want to understand the length of a string. That’s a quite fundamental string operation. In bash, you can compose ${#var} to discover the length of $var:
1
2
3
4
5
6
7
8
9
#/bin/bash
echo -n “Project Name? ”
read PNAME
if (( ${#PNAME} > 16 ))
then
echo Error: job name longer than 16 characters
else
echo ${PNAME} it is!
fi
The “((” develops an arithmetic context which is why you can get away with an unquoted greater-than indication here. If you don’t mind utilizing expr — which is an outside program — there are at least two a lot more methods to get there:
1
2
3
echo ${#STR}
expr length “${STR}”
expr match “${STR}” ‘.*’
Of course, if you enable yourself to phone call outside of bash, you might utilize awk or anything else to do this, too, however we’ll stick with expr as it is fairly lightweight.
Swiss army Knife
In fact, expr can do a great deal of string manipulations in addition to length as well as match. You can pull a substring from a string utilizing substr. It is frequently helpful to utilize index to discover a specific character in the string first. The expr program utilizes 1 as the very first character of the string. So, for example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#/bin/bash
echo -n “Full path? ”
read FFN
LAST_SLASH=0
SLASH=$( expr index “$FFN” / ) # discover very first slash
while (( $SLASH != 0 ))
do
let LAST_SLASH=$LAST_SLASH+$SLASH # point at next slash
SLASH=$(expr index “${FFN:$LAST_SLASH}” / ) # look for another
done
# now LAST_SLASH points to last slash
echo -n “Directory: ”
expr substr “$FFN” 1 $LAST_SLASH
echo -or-
echo ${FFN:0:$LAST_SLASH}
# Yes, I understand about dirname however this is an example
Enter a full path (like /foo/bar/hackaday) as well as the script will discover the last slash as well as print the name as much as as well as including the last slash utilizing two different methods. This script makes utilize of expr however likewise utilizes the syntax for bash‘s developed in substring extraction which starts at index zero. For example, if the variable FOO consists of “Hackaday”:
${FOO} -> Hackaday
${FOO:1} -> ackaday
${FOO:5:3} -> day
The very first number is an balance out as well as the second is a length if it is positive. You can likewise make either of the numbers negative, although you requirement a area after the colon if the balance out is negative. The last character of the string is at index -1, for example. A unfavorable length is shorthand for an absolute setting from the end of the string. So:
${FOO: -3} -> day
${FOO:1:-4} -> ack
${FOO: -8:-4} -> Hack
Of course, either or both numbers might be variables, as you can see in the example.
Less is More
Sometimes you don’t want to discover something, you just want to get rid of it. bash has great deals of methods to eliminate substrings utilizing fixed strings or glob-based pattern matching. There are four variations. One pair of deletions eliminate the longest as well as shortest possible substrings from the front of the string as well as the other pair does the exact same thing from the back of the string. think about this:
1
2
3
4
5
TSTR=my.first.file.txt
echo ${TSTR%.*} # prints my.first.file
echo ${TSTR%%.*} # prints my
echo ${TSTR#*fi} # prints rst.file.txt
echo $TSTR##*fi} # prints le.txt
Transformation
Of course, often you don’t want to delete, as much as you want to replace some string with one more string. You can utilize a single slash to replace the very first instance of a browse string or two slashes to replace globally. You can likewise stop working to supply a replacement string as well as you’ll get one more method to delete parts of strings. One other technique is to add a # or % to anchor the match to the begin or end of the string,just like with a deletion.
1
2
3
4
5
TSTR=my.first.file.txt
echo ${TSTR/fi/Fi} # my.First.file.txt
echo ${TSTR//fi/Fi} # my.First.File.txt
echo ${TSTR/#*./PREFIX-} # PREFIX-txt (note: always longest match)
echo ${TSTR/%.*/.backup} # my.backup (note: always longest match)
Miscellaneous
Some of the a lot more typical methods to manipulate strings in bash have to make with taking care of parameters. mean you have a script that expects a variable called OTERM to be set however you want to be sure:
1
REALTERM=${OTERM:-vt100}
Now REALTERM will have the value of OTERM or the string “vt100” if there was nothing in OTERM. often you want to set OTERM itself so while you might designate to OTERM instead of REALTERM, there is an much easier way. utilize := instead of the :- sequence. If you do that, you don’t necessarily requirement an task at all, although you can utilize one if you like:
1
echo ${OTERM:=vt100} # now OTERM is vt100 if it was empty before
You can likewise reverse the sense to ensure that you replace the value only if the primary value is not empty, although that’s not as normally useful:
1
echo ${DEBUG:+”Debug mode is ON”} # reverse -; no assignment
A a lot more drastic determine lets you print an error message to stderr as well as abort a non-interactive shell:
1
REALTERM=${OTERM:?”Error. Please set OTERM before calling this script”}
Just in Case
Converting things to upper or lower situation is relatively simple. You can supply a glob pattern that matches a single character. If you omit it, it is the exact same as ?, which matches any type of character. You can elect to modification all the matching characters or just attempt to match the very first character. right here are the obligatory examples:
1
2
3
4
5
6
7
8
9
NAME=”joe Hackaday”
echo ${NAME^} # prints Joe Hackaday (first match of any type of character)
echo ${NAME^^} # prints JOE HACKADAY (all of any type of character)
echo ${NAME^^[a]} # prints joe HAckAdAy (all a characters)
echo ${NAME,,] # prints joe hackaday (all characters)
echo ${NAME,] # prints joe Hackaday (first character matched as well as didn’t convert)
NAME=”Joe Hackaday”
echo ${NAME,,[A-H]} # prints Joe hackaday (apply pattern to all characters as well as convert A-H to lowercase)
Recent versions of bash can likewise convert upper as well as lower situation utilizing ${VAR@U} as well as ${VAR@L} together with just the very first character utilizing @u as well as @l, however your mileage may vary.
Pass the Test
You most likely recognize that when you do a basic test, that really phone calls a program:
1
2
if [ $f -eq 0 ]
then …
If you do an ls on /usr/bin, you’ll see an executable really named “[” utilized as a shorthand for the test program. However, bash has its own test in the type of two brackets:
1
2
if [[ $f == 0 ]]
then …
That test built-in can manage routine expressions utilizing =~ so that’s one more choice for matching strings:
1
if [[ “$NAME” =~ [hH]a.k ]] …
Choose Wisely
Of course, if you are doing a slew of text processing, perhaps you don’t requirement to be utilizing bash. even if you are, don’t fail to remember you can always leverage other programs like tr, awk, sed, as well as lots of others to do things like this. Sure, performance won’t be as great — most likely — however if you are anxious about performance why are you composing a script?
Unless you just vow off scripting altogether, it is great to have a few of these techniques in your back pocket. utilize them wisely.