Skip to main content

How to Reverse a String

• 2 min read
bash

Quick Answer: Reverse a String in Bash

To reverse a string in Bash, use the rev command: echo "$string" | rev. For a pure-Bash solution without external commands, use a loop with parameter expansion to build the reversed string character by character.

Quick Comparison: String Reversal Methods

MethodSpeedBest ForPortability
rev commandVery fastSimple reversalMost systems
Pure Bash loopSlowerNo dependenciesAll Bash versions
tac with trFastLine reversalAll systems
awk reversingFastComplex processingAll systems
sed reversingMediumPattern-basedGNU sed

Bottom line: Use rev for simplicity, use a loop for pure Bash without dependencies.


Reversing a String

Reversing strings is useful for palindrome checking, processing backwards data, or simple text manipulation. Bash provides several ways to reverse strings, each with different tradeoffs.

Using rev Command

The simplest method:

#!/bin/bash

string="Hello"

# Reverse using rev
reversed=$(echo "$string" | rev)
echo "Original: $string"
echo "Reversed: $reversed"
# Output: olleH

Using Parameter Expansion and Loop

Bash-native approach without external commands:

#!/bin/bash

reverse_string() {
  local string="$1"
  local reversed=""

  # Loop through string backwards
  for ((i=${#string}-1; i>=0; i--)); do
    reversed+="${string:$i:1}"
  done

  echo "$reversed"
}

result=$(reverse_string "Hello")
echo "$result"  # Output: olleH

Using tac (Line Reversal)

For multi-line strings:

#!/bin/bash

text="line1
line2
line3"

echo "$text" | tac
# Output:
# line3
# line2
# line1

Using awk for Reversal

Process strings with awk:

#!/bin/bash

string="Programming"

# Reverse character by character
reversed=$(echo "$string" | awk '{
  for (i=length($0); i>0; i--)
    printf("%c", substr($0, i, 1))
  print ""
}')

echo "Reversed: $reversed"
# Output: gnimmargorP

Palindrome Checker

Common use case - check if a string is a palindrome:

#!/bin/bash

is_palindrome() {
  local string="$1"
  local reversed=$(echo "$string" | rev)

  if [ "$string" = "$reversed" ]; then
    return 0  # Is palindrome
  else
    return 1  # Not palindrome
  fi
}

# Test
is_palindrome "racecar" && echo "Is palindrome" || echo "Not palindrome"
# Output: Is palindrome

is_palindrome "hello" && echo "Is palindrome" || echo "Not palindrome"
# Output: Not palindrome

Comparing Methods

#!/bin/bash

string="Bash"

# Method 1: rev command (fastest, external tool)
time echo "$string" | rev

# Method 2: Bash loop (no external tools, slower)
reverse_bash() {
  local s="$1" r=""
  for ((i=${#s}-1; i>=0; i--)); do
    r+="${s:$i:1}"
  done
  echo "$r"
}
time reverse_bash "$string"

# Method 3: awk (good for complex processing)
time echo "$string" | awk '{for(i=length;i>0;i--)printf"%c",substr($0,i,1);print""}'

Practical Example: Word Reversal

#!/bin/bash

reverse_words() {
  local text="$1"
  local reversed=""

  # Reverse order of words
  for word in $text; do
    reversed="$word $reversed"
  done

  echo "$reversed"
}

result=$(reverse_words "The quick brown fox")
echo "$result"
# Output: fox brown quick The

Real-World Example: Hex String Reversal

#!/bin/bash

# Useful for endianness conversion
reverse_hex() {
  local hex="$1"
  local reversed=""

  # Process pairs of hex digits
  for ((i=${#hex}-2; i>=0; i-=2)); do
    reversed+="${hex:$i:2}"
  done

  echo "$reversed"
}

# Example: byte order reversal
result=$(reverse_hex "0x12345678")
echo "$result"
# Output: 0x78563412

Case-Insensitive Palindrome

Check palindrome ignoring case:

#!/bin/bash

is_palindrome_ignore_case() {
  local string="$1"

  # Convert to lowercase
  string=$(echo "$string" | tr '[:upper:]' '[:lower:]')

  # Remove spaces and special chars
  string=$(echo "$string" | tr -d ' .,!?')

  # Check if palindrome
  local reversed=$(echo "$string" | rev)

  [ "$string" = "$reversed" ]
}

is_palindrome_ignore_case "A man, a plan, a canal: Panama" && echo "Palindrome!" || echo "Not palindrome"
# Output: Palindrome!

Practical Example: Reverse File Paths

#!/bin/bash

# Reverse directory path
reverse_path() {
  local path="$1"
  local reversed=""

  # Split by / and reverse order
  IFS='/' read -ra parts <<< "$path"

  for ((i=${#parts[@]}-1; i>=0; i--)); do
    if [ -n "${parts[$i]}" ]; then
      reversed="${reversed}/${parts[$i]}"
    fi
  done

  echo "$reversed"
}

result=$(reverse_path "/home/user/documents/file.txt")
echo "$result"
# Output: /file.txt/documents/user/home

Performance Considerations

#!/bin/bash

# For large strings, rev is significantly faster
# Test with 1000-character string

large_string=$(printf 'a%.0s' {1..1000})

# Fast: rev command
time echo "$large_string" | rev > /dev/null

# Slow: Bash loop (lots of string concatenation)
time {
  reversed=""
  for ((i=${#large_string}-1; i>=0; i--)); do
    reversed+="${large_string:$i:1}"
  done
}

Important Notes

  • rev is the fastest external tool
  • Bash loops are pure Bash but slower for large strings
  • String concatenation with += is slower than using an array
  • For production, use rev unless you need pure Bash
  • Be careful with whitespace and special characters

Quick Reference

# Reverse with rev command
echo "$string" | rev

# Reverse with Bash loop
result=""
for ((i=${#string}-1; i>=0; i--)); do
  result+="${string:$i:1}"
done

# Check palindrome
[[ "$string" == $(echo "$string" | rev) ]] && echo "Palindrome"

# Reverse words
echo "one two three" | tr ' ' '\n' | tac | tr '\n' ' '

Summary

The rev command is the simplest and fastest way to reverse strings in Bash. For palindrome checking and other text processing, combine it with other tools or use Bash loops when external commands aren’t available.