String comparisons are a fundamental part of Bash scripting, allowing you to manipulate and make decisions based on text data. In this blog post, we’ll explore various methods and operators for comparing strings in Bash, along with practical examples and best practices.

Basic String Comparison Operators

Bash provides several operators for comparing strings:

  • = or ==: Equal to (use == inside double brackets [[ ]])
  • !=: Not equal to
  • <: Less than (in ASCII alphabetical order)
  • >: Greater than (in ASCII alphabetical order)
  • -z: String is null (zero length)
  • -n: String is not null (non-zero length)

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

str1="hello"
str2="world"

if [ "$str1" = "$str2" ]; then
echo "Strings are equal"
else
echo "Strings are not equal"
fi

if [ -z "$str1" ]; then
echo "String is empty"
fi

Using Double Brackets

Double brackets [[ ]] provide more features and are generally preferred for string comparisons:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

name="Alice"

if [[ "$name" == "Alice" ]]; then
echo "Hello, Alice!"
fi

if [[ "$name" != "Bob" ]]; then
echo "You're not Bob"
fi

Case-Insensitive Comparisons

To perform case-insensitive comparisons, use the shopt command to set nocasematch:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

shopt -s nocasematch

name="alice"

if [[ "$name" == "ALICE" ]]; then
echo "Names match (case-insensitive)"
fi

shopt -u nocasematch # Turn off nocasematch

Pattern Matching

You can use pattern matching within double brackets:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

filename="document.txt"

if [[ "$filename" == *.txt ]]; then
echo "This is a text file"
fi

if [[ "$filename" == doc* ]]; then
echo "Filename starts with 'doc'"
fi

Regular Expressions

Bash supports basic regular expressions with the =~ operator:

1
2
3
4
5
6
7
8
9
#!/bin/bash

email="user@example.com"

if [[ "$email" =~ [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4} ]]; then
echo "Valid email format"
else
echo "Invalid email format"
fi

Comparing String Lengths

You can compare string lengths using the -gt, -lt, or -eq operators:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

str1="hello"
str2="hi"

if [ ${#str1} -gt ${#str2} ]; then
echo "str1 is longer than str2"
elif [ ${#str1} -lt ${#str2} ]; then
echo "str1 is shorter than str2"
else
echo "str1 and str2 have the same length"
fi

Substring Check

To check if a string contains a substring:

1
2
3
4
5
6
7
8
#!/bin/bash

sentence="The quick brown fox jumps over the lazy dog"
word="fox"

if [[ "$sentence" == *"$word"* ]]; then
echo "The sentence contains the word '$word'"
fi

Sorting Strings

You can use the sort command to compare and sort strings:

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

string1="apple"
string2="banana"

if [[ "$(echo -e "$string1\n$string2" | sort | head -n1)" == "$string1" ]]; then
echo "$string1 comes before $string2 alphabetically"
else
echo "$string2 comes before $string1 alphabetically"
fi

Comparing Prefixes and Suffixes

To check if a string starts or ends with a specific substring:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

filename="document.pdf"

if [[ "$filename" == doc* ]]; then
echo "Filename starts with 'doc'"
fi

if [[ "$filename" == *.pdf ]]; then
echo "File is a PDF"
fi

Null or Empty String Checks

Always quote variables to handle null or empty strings correctly:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

empty_var=""
unset_var

if [ -z "$empty_var" ]; then
echo "empty_var is empty"
fi

if [ -z "$unset_var" ]; then
echo "unset_var is null or unset"
fi

Conclusion

Mastering string comparisons in Bash is essential for effective script writing. From basic equality checks to pattern matching and regular expressions, these techniques allow you to manipulate and validate text data efficiently.
Remember to always quote your variables to prevent word splitting and globbing issues. Also, prefer using double brackets [[ ]] for string comparisons as they provide more features and are less prone to errors.
By incorporating these string comparison techniques into your Bash scripts, you’ll be able to handle text processing tasks more effectively and create more robust and flexible scripts.