Parameter expansion is a powerful feature of Bash which will allow you to work on strings with great ease and just a little typing. Here are 10 simple examples on how to use just a bit of the power of parameter expansion to quickly modify and work on strings.
Print a Substring from a String by Specifying Character Start and End Position
This example will print the next three characters starting at the character with position 1. Indexing starts at 0.
Example:
var="abcdef" echo ${var:1:3}
Output:
bcd
The string bcd will be printed.
Replace a Substring with Another String
The general form is ${VARIABLE/PATTERN/STRING} and will replace the first occurrence of PATTERN with STRING.
Example:
var="apples and oranges" echo ${var/apples/cherries}
Output:
cherries and oranges
In the above example the text apples has been replaced by cherries. If you want to substitute all occurrences of a string, use the // operator like this:
Example:
var="apples and oranges and more apples" echo ${var//apples/cherries}
Output:
cherries and oranges and more cherries
Remove a Substring from a String
You can do it using the same method as above, but not specifying the STRING.
Example:
var="apples and oranges" echo ${var/apples/}
Output:
and oranges
You can even omit the trailing forward slash (e.g. echo ${var/apples}).
Remove a Pattern from the End of a String
This will only remove a pattern which is located at the end of a string, and will use the ${VARIABLE%PATTERN} form.
Example:
var="apples and oranges" echo ${var%oranges}
Output:
apples and
This can be useful in scripts or one-liners to change or remove file extensions.
Convert Uppercase to Lowercase or Vice Versa
This will convert lowercase characters to uppercase characters:
Example:
var="abcdef" echo ${var^^}
Output:
ABCDEF
And this is used to convert all uppercase characters in a variable string with lowercase ones. Characters which are already lowercase remain unchanged:
Example:
var="ABCDEF" echo ${var,,}
Output:
abcdef
You can use it for file renaming, for example to rename all the .JPG files in a directory which have uppercase characters:
for i in *.JPG; do mv "$i" "${i,,}" done
Access All Parameters Given to a Script Starting at a Position to the End
Say you have a script which takes a variable number of parameters and you need to perform some operation on all the parameters starting with the third one.
Example:
echo ${@:3}
Output:
./myscript.sh abc def ghi jkl ghi jkl
Will print all the arguments starting with the third one.
Print a File Name without the Extension
This is an example similar to the above example for removing a pattern from the end of a string, only now we will use the * wildcard to remove any extension of a filename (whatever follows after the last dot, including it).
Example:
var="my_filename.txt" echo ${var%.*}
Output:
my_filename
Print a Filename Extension Only
This example uses the wildcard and the method used to remove a pattern from the beginning of a string.
Example:
var="my_filename.txt" echo ${var#*.}
Output:
txt
Print the Filename from a Path
This example uses the ## operator, which is used to return the longest string which matches the pattern. The difference between # and ## is that the first one will return the shortest string which matches a pattern, while the latter will return the longest string which matches the same pattern.
Example:
var="/usr/bin/emacs" echo ${var##*/}
Output:
emacs
Print the Path without the Filename
Example:
var="/usr/bin/emacs" echo ${var%/*}
Output:
/usr/bin
Substring substitution will print and offset and a length and not till the position of the character like stated.
echo ${PARAMETER:OFFSET:LENGTH}
DAYYYUMN! This is actually mind blowing… I didn’t know about any of these tricks. So much nicer than having chunks of sed in your one liner cmdline hacks. Thanks!