<<< Back to Tips Index

20th June 2017

How to edit a string within a variable

The shell is a rather good tool for manipulating strings. The Bash shell, in particular (which is the default on almost every Linux distribution, and available on almost every Unix, too), has some strong string manipulation utilities built-in.

One thing that it includes looks rather similar to a familiar tools such as sed. You can process the value of a variable, whilst substituting some subset of its content for another value, with "/foo/bar" style syntax.

For example, if "$MESSAGE" is "Develop a passion for learning. If you do, you will never cease to grow." then you can work with it as follows:

$ MESSAGE="Develop a passion for learning. If you do, you will never cease to grow."
$ echo ${MESSAGE}
Develop a passion for learning. If you do, you will never cease to grow.

# Replace part of the text.
# Replace "passion" with "desire":
$ echo ${MESSAGE/passion/desire}
Develop a desire for learning. If you do, you will never cease to grow.

# Remove part of the text.
# Here, remove "passion":
$ echo ${MESSAGE/passion}
Develop a for learning. If you do, you will never cease to grow.

# Replace the first match in the text.
# Here, "e" becomes "E":
$ echo ${MESSAGE/e/E}
DEvelop a passion for learning. If you do, you will never cease to grow.
$ 

# Replace all matches in the text, by adding an extra slash (/).
# Here, all "e" become "E":
$ echo ${MESSAGE//e/E}
DEvElop a passion for lEarning. If you do, you will nEvEr cEasE to grow.
$ 

There is more, too - you can specify whether the matches should be at the start or the end of the string. Take this (fictional) phone number:

$ PHONE_NUMBER=07700700307

# Replace the first "0" with "4":
$ echo ${PHONE_NUMBER/0/4}
47700700307	# First 0 becomes 4

# Start the pattern with an extra "/"
# to replace all "0" with "4":
$ echo ${PHONE_NUMBER//0/4}
47744944347	# All 0 become 4
$ 

# Replace first (and only) "03" with "04":
$ echo ${PHONE_NUMBER/03/04}
07700700407	# First 03 becomes 04
# Replace first "07" with "04":
$ echo ${PHONE_NUMBER/07/04}
04700700307	# First 07 becomes 04
$ 

# Replace all "07" with "04":
$ echo ${PHONE_NUMBER//07/04}
04700400304	# All 07 become 04
$

# Do the same again, but only if the "03"
# or "07" are at the start of the number:
$ echo ${PHONE_NUMBER/#03/04}
07700700307	# Unchanged
$ echo ${PHONE_NUMBER/#07/04}
04700700307	# First 07 becomes 04
$ 

# Do the same, but only at the end:
$ echo ${PHONE_NUMBER/%07/04}
07700700304	# Final 07 becomes 04
$ echo ${PHONE_NUMBER/%03/04}
07700700307	# Unchanged
$ 

From the bash documentation:

       ${parameter/pattern/string}
              Pattern substitution.  
The pattern is expanded to produce a pattern just as in pathname expansion.  Parameter is expanded and the longest match of pattern  against  its value  is  replaced  with  string.   
If  pattern begins with /, all matches of pattern are replaced with string.  
Normally only the first match is replaced.  
If pattern begins with #, it must match at the beginning of the expanded value of parameter.  
If pattern begins with %, it must match at the end of the expanded value  of  parameter.   
If  string  is null, matches of pattern are deleted and the / following pattern may be omitted.  
If parameter is @ or *, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list.  
If parameter is an array variable subscripted with @ or *, the  substitution  operation  is applied to each member of the array in turn, and the expansion is the resultant list.

 

Invest in your career. Buy my Shell Scripting Tutorial today:

 

Steve's Bourne / Bash shell scripting tips
Share on Twitter Share on Facebook Share on LinkedIn Share on Identi.ca Share on StumbleUpon