bash string - ghdrako/doc_snipets GitHub Wiki
- https://www.thegeekstuff.com/2010/07/bash-string-manipulation/
- https://earthly.dev/blog/bash-string/
- https://tldp.org/LDP/abs/html/string-manipulation.html
Assigning content to a variable and printing its content
VariableName='value'
echo $VariableName
# or
VariableName="value"
echo ${VariableName}
# or
VariableName=value
echo "$VariableName"
String length
String Length: Determine the length of a string using ${variable}
.
length=${message}
${#string} # Identify String Length inside Bash Shell Script
variableName=value
echo ${#variablename}
words="here are some words"
echo "'$words' is ${#words} characters long
Concatenate strings inside Bash Shell using variables
var=${var1}${var2}${var3}
# or
var=$var1$var2$var3
# or
var="$var1""$var2""$var3"
# The following will insert "**" between the strings
var=${var1}**${var2}**${var3}
# or
var=$var1**$var2**$var3
# or
var="$var1"**"$var2"**"$var3"
# The following concatenate the strings using space:
var=${var1} ${var2} ${var3}
# or
var="$var1" "$var2" "$var3"
# or
echo ${var1} ${var2} ${var3}
var=$var1 $var2 $var3 # not work !!!
Concatenate string using +=
concat=""
concat+="1"
concat+="2"
echo "$concat"
12
Concatenate strings inside Bash Shell using an array
o create an array:
arr=("value1" value2 $value3)
To print an array:
echo ${arr[@]}
To print length of an array:
echo ${#arr[@]}
Using indices (index starts from 0):
echo ${arr[index]}
Note: echo ${arr} is the same as echo ${arr[0]}
Extract a substring from a string
Substring Extraction: Extract part of a string using
${variable:start:length}.
message="Hello, World!"
echo ${message:0:5}
Outputs: Hello
${string:position} # Extract substring from $string at $position
${string:position:length} # Extract $length of characters substring from $string starting from $position
${string:position} --> returns a substring starting from $position till end
${string:position:length} --> returns a substring of $length characters starting from $position.
Example
$ NAME=Baeldung
$ echo ${NAME:6}
ng
$ echo ${NAME:0:4}
Bael
$ word="bash"
$ echo "${word:0:1}"
b
$ word="bash"
$ echo "${word:0:1}"
b
$ word="bash"
$ echo "Head: ${word:0:1}"
$ echo "Rest: ${word:1}"
OutputHead: b
Rest: ash
Note: $length and $position must be always greater than or equal to zero. If the $position is less than 0, it will print the complete string. If the $length is less than 0, it will raise an error and will not execute.
Bash Last Character
word="bash"
$ echo "${word:(-1)}"
$ echo "${word:(-2)}"
$ echo "${word:(-3)}"
Outputh
sh
ash
Remove the last characters from string
word="bash"
echo "${word:0:${#word}-1}"
echo "${word:0:${#word}-2}"
echo "${word:0:${#word}-3}"
bas
ba
b
Remove the last characters from string use the pattern expansion
$ word="bash"
$ echo "${word%?}
$ echo "${word%??}
$ echo "${word%???}
bas
ba
b
If the regex doesn’t match, it doesn’t remove anything.
$ word="one"
$ echo "${word%????}" # remove first four characters
one
Substring matching:
In Bash, the shortest and longest possible match of a substring can be found and deleted from either front or back.
Syntax:
To delete the shortest substring match from front of $string:
${string#substring}
To delete the shortest substring match from back of $string:
${string%substring}
To delete the longest substring match from front of $string:
${string##substring}
To delete the shortest substring match from back of $string of $string:
${string%%substring}
Pattern Matching
if [ "file.jpg" = *.jpg ](/ghdrako/doc_snipets/wiki/-"file.jpg"-=-*.jpg-); then echo "is jpg"; fi
Pattern Matching - extended globbing
- *(pattern) – matches any number of occurrence of pattern
- ?(pattern) – matches zero or one occurrence of pattern
- +(pattern) – matches one or more occurrence of pattern
- !(pattern) – negates the pattern, matches anything that doesn’t match the pattern
$ shopt -s extglob
$ if [ "file.jpg" = *.jp?(e)g ](/ghdrako/doc_snipets/wiki/-"file.jpg"-=-*.jp?(e)g-); then echo "is jpg"; fi
Pattern Matching - regular expression
$ if [ "file.jpg" =~ .*\.jpe?g ](/ghdrako/doc_snipets/wiki/-"file.jpg"-=~-.*\.jpe?g-); then echo "is jpg"; fi
is jpg
We can use Extended Regular Expressions here, like when calling grep with the -E flag. If we use the capture groups, they’ll be stored in the BASH_REMATCH
array variable and can be accessed later.
filename="bash.string.txt"
# Shortest Substring Match
echo ${filename#*.} # output -> string.txt
echo ${filename%.*} # output -> bash.string
# Longest Substring Match
echo ${filename##*.} # txt
echo ${filename%%.*} # bash
${string/pattern/replacement} # Replace only first match
filename="bash.string.txt"
echo "After Replacement:" ${filename/str*./operations.} # output -> bash.operations.txt
${string//pattern/replacement} # Replace all the matches
filename="Path of the bash is /bin/bash"
echo "After Replacement:" ${filename//bash/sh} # Path of the sh is /bin/sh
${string/#pattern/replacement} # syntax replaces with the replacement string, only when the pattern matches beginning of the $string.
${string/%pattern/replacement} # syntax replaces with the replacement string, only when the pattern matches at the end of the given $string.
filename="/root/admin/monitoring/process.sh"
echo "Replaced at the beginning:" ${filename/#\/root/\/tmp} # /tmp/admin/monitoring/process.sh
echo "Replaced at the end": ${filename/%.*/.ksh} # /root/admin/monitoring/process.ksh
Bash String Replace
$ phrase="create to create"
$ echo "${phrase/create/make}" # replace only first
make to create
echo "${phrase//create/make}" # replaca all
make to make
$ number="Phone Number: 234-234-2343"
$ echo "${number//[0-9]/X}
Phone number: XXX-XXX-XXXX
String condition
if [ "one" == "one" ](/ghdrako/doc_snipets/wiki/-"one"-==-"one"-); then
echo "Strings are equal."
fi
if [ "one" != "two" ](/ghdrako/doc_snipets/wiki/-"one"-!=-"two"-); then
echo "Strings are not equal."
fi
if [ "aaa" < "bbb" ](/ghdrako/doc_snipets/wiki/-"aaa"-<-"bbb"-); then
echo "aaa is smaller."
fi
Output:
Strings are equal.
Strings are not equal.
aaa is smaller.
Compare strings to globs
file="todo.gz"
if [ "$file" = *.gz ](/ghdrako/doc_snipets/wiki/-"$file"-=-*.gz-); then # (Note that the glob is not quoted.)
echo "Found gzip file: $file"
fi
if [ "$file" = todo.* ](/ghdrako/doc_snipets/wiki/-"$file"-=-todo.*-); then
echo "Found file named todo: $file"
fi
Output
Found gzip file: todo.gz
Found file named todo: todo.gz
Bash String Regex Match
name="aardvark"
if [ "$name" =~ ^aa ](/ghdrako/doc_snipets/wiki/-"$name"-=~-^aa-); then # checking if a string starts with aa
echo "Starts with aa: $name"
fi
Output
Starts with aa: aardvark
name="aardvark"
if [ "$name" =~ dvark ](/ghdrako/doc_snipets/wiki/-"$name"-=~-dvark-); then # string contains a certain substring
echo "Contains dvark: $name"
fi
Output
Contains dvark: aardvark
Split Strings using regexp group
if [ "1](/ghdrako/doc_snipets/wiki/tom|1982"-=~-(.*)\|(.*)\|(.*)-);
then
echo "ID = ${BASH_REMATCH[1]}" ;
echo "Name = ${BASH_REMATCH[2]}" ;
echo "Year = ${BASH_REMATCH[3]}" ;
else
echo "Not proper format";
fi
Output
ID = 1
Name = tom
Year = 1982
Split string using $IFS Internal Field Separator
By default, bash treats spaces as the delimiter between separate elements.
list="foo bar baz"
for word in $list; do # <-- $list is not in double quotes
echo "Word: $word"
done
Output
Word: foo
Word: bar
Word: baz
If you wrap space-delimited items in brackets, you get an array.
list="foo bar baz"
array=($list)
echo "Zeroth: ${array[0]}"
echo "First: ${array[1]}"
echo "Whole Array: ${array[*]}"
Output
Zeroth: foo
First: bar
Whole Array: foo bar baz
text="1|tom|1982"
IFS='|'
array=($text)
unset IFS;
echo "ID = ${array[1]}" ;
echo "Name = ${array[2]}" ;
echo "Year = ${array[3]}" ;
Output
ID = 1
Name = tom
Year = 1982
trimming the whitespace aroud string
echo " lol " | xargs
lol