Bash string manipulation

When I write bash scripts in my terminal, I often need to manipulate strings.

Unfortunately, I often forget how to do this properly in bash, so I thought I’d write a blog article for me to remember better in the future. Hopefully it will be helpful for some of you developers out there as well.

String manipulation in bash is not hard, but I find some of the notation a bit cumbersome especially when normally working more with Python or other languages. But let’s dive in:

String concatenation

How can I concatenate two strings $a and $b in bash?

Just write them next to each other:

a='Hello'
b=' World!'

echo $a$b
Output: Hello World!

Get a substring of a string

How do I get the substring of an existing variable string in bash?

Use the from:len notation (0-indexed!):

bash='Have fun in bash'
#     0123456789...

echo ${bash:5:3}
Output: fun

So it starts at index 5 ‘f’ and takes 3 characters -> ‘fun’.

Note that you can also use negative indexing with the somewhat awkward bracket notation:

bash='Have fun in bash'

echo ${bash:(-4):4}
Output: bash

If you omit the second length index, then it just assumes end of the string, so ${bash:(-4):4} is the same as ${bash:(-4)} in this case.

String length

How do I determine the length of a string in bash?

Use the # sign:

hi='Hello World'

echo ${#hi}
Output: 11

Replace first substring match in a variable

How can I replace the first match of a ‘substring’ with the string ‘replacement’ in a bash variable called $variable?

It’s simple:

${variable/substring/replacement}

Example program:

original='Hello World to the World'

out=${original/World/Bash}

echo $out
Output: Hello Bash to the World

Replace all matches in a variable

How can I replace all matches of the string ‘substring’ with the string ‘replacement’ in a bash variable called $variable?

Simply use a double-forward slash:

${variable//substring/replacement}

Example program:

original='Hello World to the World'

out=${original//World/Bash}

echo $out
Output: Hello Bash to the Bash

Substring deletion

How do I delete a substring of a variable in bash?

Use the replacement operation above and replace with nothing! You can omit the last part as well:

hi='Hello World'

echo ${hi/ World}
# Same as ${hi/ World/}
Output: Hello

Of course, you can use the // again to remove all substring occurrences:

hi='Have some bash fun with the bash'

echo ${hi//bash}
Output: Have some fun with the

Check if a substring exists in a string

How can I check if a string contains a substring and only then execute some code in bash?

Use the following if clause:

hello='Hello bash world'

if [[ $hello = *"bash"* ]]; then
  echo 'Bash has been detected' 
fi

if [[ $hello = *"smash"* ]]; then
  echo 'Smash has been detected' 
else
  echo 'Smash has NOT been detected'
fi
Output: Bash has been detected
        Smash has NOT been detected

Split string into array

How do I split a string at a certain character and get the sub-parts as an array.

This one is a bit hackier for my taste. We are using the bash read command and passing it the flag -a output to read an array into the variable $output. We are using the IFS(internal field separator) env variable to specify our split character ('_' in my example). Finally, we are using the <<< redirector to using an existing string variable for this (otherwise read expects to read user input):

start='Hello_bash_world'

IFS=_ read -a output <<< $start

echo ${output[0]}
echo ${output[1]}
echo ${output[2]}
echo ${output[@]}
Output: Hello
        bash
        world
        Hello bash world

Note that ${variable[index]} is the notation to access arrays by index and the special index @ prints all of the array concatenated by spaces.