Skip to main content

How to Count Characters in a String in Bash

• 5 min read
bash string manipulation string length character count

Quick Answer: Get String Length in Bash

To get the length of a string in Bash, use parameter expansion: ${#text}. This returns the number of characters in the variable. It’s the fastest method because it uses built-in Bash functionality with no external commands.

Quick Comparison: String Length Methods

MethodSpeedBest ForCompatibility
Parameter expansionFastestSimple length checksAll Bash versions
wc -cVery fastPiped inputAll systems
awk length()Very fastComplex processingAll systems
exprFastLegacy systemsAll systems
printfFastFormatted outputAll Bash versions

Bottom line: Use parameter expansion for maximum speed. Use wc or awk when processing piped data.


Parameter expansion ${#variable} is the fastest and cleanest way to get string length. It uses built-in Bash functionality with no external commands or process overhead. When your text is in a variable, this is always your best choice.

Basic String Length

Here’s the fundamental pattern—use a hash symbol before the variable name:

text="Hello"
length=${#text}
echo "$length"
# Output: 5

The # inside the braces tells Bash to return the length instead of the value. This works with any variable containing a string, no matter the content.

Length Directly in Conditions

You can use string length directly in comparisons without storing it first:

password="secret123"

if [ ${#password} -lt 8 ]; then
  echo "Password too short"
else
  echo "Password is valid"
fi

This checks the length in one step. The comparison operators (-lt, -gt, -eq) work with numeric lengths.

When to Use Parameter Expansion

Use parameter expansion when:

  • You have a string in a variable (the common case)
  • You need the fastest performance
  • You want simplicity and readability
  • You’re checking string length in conditions
  • You’re validating input length

Avoid it when:

  • You’re reading from a pipe (use wc instead)
  • You need complex text processing (use awk)
  • The string contains newlines and you want byte count (use wc)

Method 2: Using wc Command

The wc command counts bytes or characters, useful when reading from pipes or files. It’s an external command, so it’s slower than parameter expansion, but it’s standard across all Unix systems and handles piped input naturally.

Count Characters in Piped Input

When data comes from a pipe, you can use wc -c:

text="Hello"
echo -n "$text" | wc -c
# Output: 5

The -n flag in echo prevents adding a newline, so wc -c counts only the actual text. Without -n, you’d count the newline too.

Count Bytes vs Characters

For ASCII strings, characters and bytes are the same. But for Unicode, be careful:

text="Hëllo"  # Contains non-ASCII character
echo -n "$text" | wc -c  # Counts bytes (6 on UTF-8)
echo ${#text}             # Counts characters (5)

Parameter expansion counts characters; wc -c counts bytes. For Unicode strings, use parameter expansion to count actual characters.

When to Use wc

Use wc when:

  • Reading from pipes or files (more natural)
  • You need compatibility with non-Bash scripts
  • You’re counting bytes specifically
  • You’re processing file input

Skip it when:

  • Working with variables (parameter expansion is faster)
  • You need Unicode character count (use parameter expansion)

Method 3: Using awk

awk is powerful when you need length information as part of complex text processing. It has a built-in length() function and integrates naturally with data transformation.

Get Length with awk

text="Hello"
length=$(echo "$text" | awk '{print length}')
echo "$length"
# Output: 5

The length function (without parentheses) returns the length of the current line. This is useful when you’re already using awk to process text.

Combine Length with Other Processing

Where awk really shines is when you need length as part of broader processing:

text="apple"
result=$(echo "$text" | awk '{print "Word: " $0 ", Length: " length}')
echo "$result"
# Output: Word: apple, Length: 5

You’re getting length and building a formatted output in one command.

When to Use awk

Use awk when:

  • You’re already processing text with awk
  • You need length combined with other operations
  • You’re processing structured data (CSV, etc.)
  • You want to work with fields and records

Avoid it when:

  • Simple length check needed (parameter expansion is faster)
  • Reading from variables (parameter expansion is simpler)

Practical Examples

Example 1: Validate Password Length

#!/bin/bash

password="$1"
min_length=8
max_length=32

if [ ${#password} -lt $min_length ]; then
  echo "Password too short (minimum $min_length characters)"
  exit 1
elif [ ${#password} -gt $max_length ]; then
  echo "Password too long (maximum $max_length characters)"
  exit 1
else
  echo "Password length is valid"
fi

This validates that a password meets length requirements. Simple, clear, and fast.

Example 2: Check if String is Empty

#!/bin/bash

text="$1"

if [ ${#text} -eq 0 ]; then
  echo "Error: No input provided"
  exit 1
else
  echo "Received: $text (${#text} characters)"
fi

A common pattern for validating that required input was provided.

Example 3: Extract File Extension Using Length

#!/bin/bash

filename="document.txt"
length=${#filename}

# Get last 4 characters (the extension)
extension="${filename:$((length-4))}"
echo "Extension: $extension"
# Output: Extension: .txt

Using length to calculate the position for extracting the extension. The ${string:start:length} syntax uses the length to find where the extension starts.

Example 4: Truncate String to Maximum Length

#!/bin/bash

text="This is a very long string that needs truncating"
max_length=20

if [ ${#text} -gt $max_length ]; then
  truncated="${text:0:$max_length}..."
  echo "Truncated: $truncated"
else
  echo "Text: $text"
fi

Check if text exceeds a limit, and if so, truncate it. This is useful for display purposes.

Example 5: Count Array Elements

#!/bin/bash

# Array length uses similar syntax
fruits=(apple banana orange mango kiwi)
echo "Number of fruits: ${#fruits[@]}"
# Output: Number of fruits: 5

# You can also get specific array element length
echo "Length of first fruit: ${#fruits[0]}"
# Output: Length of first fruit: 5

For arrays, ${#array[@]} gives the number of elements, while ${#array[i]} gives the length of an element.

Example 6: Count Occurrences of a Character

#!/bin/bash

text="hello world"
# Remove all non-'o' characters, then count length
count=${text//[!o]/}
num_o=${#count}

echo "The letter 'o' appears $num_o times"
# Output: The letter 'o' appears 2 times

This clever technique uses parameter expansion to remove everything except the character you’re counting, then gets the length of what remains.

Example 7: Validate Username Format

#!/bin/bash

username="$1"
min_length=3
max_length=20

if [ ${#username} -lt $min_length ]; then
  echo "Username too short (minimum $min_length characters)"
  exit 1
elif [ ${#username} -gt $max_length ]; then
  echo "Username too long (maximum $max_length characters)"
  exit 1
elif [[ ! "$username" =~ ^[a-zA-Z0-9_]+$ ]]; then
  echo "Username contains invalid characters"
  exit 1
else
  echo "Username is valid"
fi

Combine length checks with pattern validation for complete input validation.

Quick Reference

# Get string length
${#text}

# Check if empty
[ ${#text} -eq 0 ]

# Check minimum length
[ ${#text} -lt 8 ]

# Check maximum length
[ ${#text} -gt 20 ]

# Get array length
${#array[@]}

# Get specific element length
${#array[0]}

# Using in piped input
echo "$text" | wc -c

# Count character occurrences
count=${text//[!x]/}  # Count 'x'
${#count}

Summary

Use parameter expansion ${#variable} for string length in 99% of cases. It’s the fastest, clearest way to get the length of a string stored in a variable. The syntax is simple, the performance is optimal, and it handles Unicode characters correctly. Only reach for wc when you’re working with piped input or file data, and use awk when you’re already processing complex text.