How to Compare Strings in Bash

By 

Updated on

7 min read

Bash Compare Strings

When writing Bash scripts, you will often need to compare two strings to check if they are equal or not. Two strings are equal when they have the same length and contain the same sequence of characters.

This guide explains how to compare strings in Bash using comparison operators, pattern matching, and regular expressions.

Comparison Operators

When comparing strings in Bash, you can use the following operators:

  • string1 = string2 and string1 == string2 - The equality operator returns true if the operands are equal. Use = with the test ([) command and == with the [[ command.
  • string1 != string2 - The inequality operator returns true if the operands are not equal.
  • string1 =~ regex - The regex operator returns true if the left operand matches the extended regular expression on the right.
  • string1 > string2 - The greater than operator returns true if the left operand is greater than the right in lexicographical (alphabetical) order.
  • string1 < string2 - The less than operator returns true if the left operand is less than the right in lexicographical order.
  • -z string - True if the string length is zero.
  • -n string - True if the string length is non-zero.

A few points to keep in mind when comparing strings:

  • A blank space must be used between the binary operator and the operands.
  • Always use double quotes around variable names to avoid word splitting or globbing issues.
  • Bash does not segregate variables by type. Variables are treated as integer or string depending on the context.

Check if Two Strings are Equal

The most common string comparison checks whether two strings are equal or not.

The following script uses the if statement and the [ test command with the = operator:

sh
#!/bin/bash

VAR1="Linuxize"
VAR2="Linuxize"

if [ "$VAR1" = "$VAR2" ]; then
    echo "Strings are equal."
else
    echo "Strings are not equal."
fi

When the script is executed, it prints the following output:

output
Strings are equal.

Here is another example that takes input from the user and compares the given strings. This example uses the [[ command with the == operator:

sh
#!/bin/bash

read -p "Enter first string: " VAR1
read -p "Enter second string: " VAR2

if [[ "$VAR1" == "$VAR2" ]]; then
    echo "Strings are equal."
else
    echo "Strings are not equal."
fi

Run the script and enter the strings when prompted:

output
Enter first string: Linuxize
Enter second string: Ubuntu
Strings are not equal.

You can also use logical AND (&&) and OR (||) for inline comparisons:

Terminal
[[ "string1" == "string2" ]] && echo "Equal" || echo "Not equal"
output
Not equal

Check if a String Contains a Substring

There are multiple ways to check if a string contains a substring.

One approach is to surround the substring with asterisk symbols (*), which match any sequence of characters:

sh
#!/bin/bash

VAR='GNU/Linux is an operating system'
if [[ $VAR == *"Linux"* ]]; then
    echo "It is there."
fi

The script will echo the following:

output
It is there.

Another option is to use the regex operator =~:

sh
#!/bin/bash

VAR='GNU/Linux is an operating system'
if [[ $VAR =~ .*Linux.* ]]; then
    echo "It is there."
fi

The period followed by an asterisk (.*) matches zero or more occurrences of any character except a newline.

Check if a String is Empty

You will often need to check whether a variable is an empty string or not. You can do this with the -z and -n operators.

The -z operator returns true if the string is empty:

sh
#!/bin/bash

VAR=''
if [[ -z $VAR ]]; then
    echo "String is empty."
fi
output
String is empty.

The -n operator returns true if the string is not empty:

sh
#!/bin/bash

VAR='Linuxize'
if [[ -n $VAR ]]; then
    echo "String is not empty."
fi
output
String is not empty.

Case-Insensitive Comparison

By default, string comparisons in Bash are case-sensitive. There are two ways to perform case-insensitive comparisons.

The first approach uses the ,, parameter expansion to convert both strings to lowercase before comparing:

sh
#!/bin/bash

VAR1="Hello"
VAR2="hello"

if [[ "${VAR1,,}" == "${VAR2,,}" ]]; then
    echo "Strings are equal (case-insensitive)."
fi
output
Strings are equal (case-insensitive).

The second approach uses shopt -s nocasematch, which makes all pattern matching and == comparisons case-insensitive within the current shell:

sh
#!/bin/bash

shopt -s nocasematch

VAR1="Hello"
VAR2="hello"

if [[ "$VAR1" == "$VAR2" ]]; then
    echo "Strings are equal (case-insensitive)."
fi

shopt -u nocasematch

Always restore the default behavior with shopt -u nocasematch after the comparison to avoid affecting the rest of your script.

Pattern Matching

When using the [[ command, the == operator supports glob-style pattern matching on the right side. The pattern is not quoted so that Bash interprets the wildcards.

The following example checks whether a string starts with “Linux”:

sh
#!/bin/bash

VAR="Linuxize"
if [[ "$VAR" == Linux* ]]; then
    echo "Starts with Linux."
fi
output
Starts with Linux.

You can also use ? to match a single character, or [...] to match a character class:

sh
#!/bin/bash

VAR="file1.txt"
if [[ "$VAR" == file[0-9].txt ]]; then
    echo "Matches the pattern."
fi
output
Matches the pattern.

Comparing Strings with the Case Statement

Instead of using test operators, you can use the case statement to compare strings against multiple patterns:

sh
#!/bin/bash

VAR="Arch Linux"

case $VAR in
    "Arch Linux")
        echo "Arch Linux matched."
        ;;
    Fedora | Debian)
        echo "Fedora or Debian matched."
        ;;
    *)
        echo "No match found."
        ;;
esac
output
Arch Linux matched.

The case statement is especially useful when you need to compare a string against more than two or three values.

Lexicographic Comparison

Lexicographic comparison compares two strings alphabetically, character by character from left to right. This is useful when you need to sort or order strings.

The following script compares two strings lexicographically:

sh
#!/bin/bash

VAR1="Linuxize"
VAR2="Ubuntu"

if [[ "$VAR1" > "$VAR2" ]]; then
    echo "${VAR1} is lexicographically greater than ${VAR2}."
elif [[ "$VAR1" < "$VAR2" ]]; then
    echo "${VAR2} is lexicographically greater than ${VAR1}."
else
    echo "Strings are equal."
fi
output
Ubuntu is lexicographically greater than Linuxize.

The > and < operators compare based on the ASCII value of each character. Uppercase letters have lower ASCII values than lowercase letters, so "A" is less than "a".

Quick Reference

OperatorDescription
=, ==Equal (use = with [, == with [[)
!=Not equal
=~Regex match
<Less than (lexicographic)
>Greater than (lexicographic)
-zString is empty
-nString is not empty
*pattern*Substring/glob match (with [[)
${var,,}Convert to lowercase
${var^^}Convert to uppercase

FAQ

What is the difference between [ and [[ in Bash?
[ is the POSIX-compatible test command. [[ is a Bash built-in that supports pattern matching, regex, and does not require quoting variables to prevent word splitting. Prefer [[ in Bash scripts.

How do I compare strings case-insensitively?
Either convert both strings to the same case with ${var,,} (lowercase) or ${var^^} (uppercase), or enable shopt -s nocasematch before the comparison.

What is the difference between = and == for string comparison?
Both check for equality. The = operator is POSIX-compliant and works with [ and [[. The == operator works only with [[ and also supports glob patterns on the right side.

How do I check if a variable is set and not empty?
Use [[ -n "$VAR" ]] to check that the string is not empty. To also verify the variable is set, use [[ -v VAR ]] (Bash 4.2+).

What is the difference between string comparison and numeric comparison?
String operators (==, !=, <, >) compare character by character. Numeric operators (-eq, -ne, -lt, -gt) compare integer values. For example, [[ "02" == "2" ]] is false (different strings), but [[ 02 -eq 2 ]] is true (same number).

Conclusion

Comparing strings is one of the most fundamental operations in Bash scripting. Use == and != for equality checks, =~ for regex matching, and -z and -n to test for empty strings. You can also check our guide about string concatenation .

Tags

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page