Bash Cheatsheet

Strings

Use this Bash reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

String Assignment and Basic Operations

str="Hello, World"
empty=""
num_str="42"

# Concatenation
a="Hello"
b=" World"
c="${a}${b}"          # "Hello World"
c+=" Again"           # append in-place → "Hello World Again"

# Length
echo ${#str}          # 12

# Repeat (no built-in — use printf or loop)
printf '%.0s-' {1..20}   # 20 dashes
printf '%20s' | tr ' ' '-'   # another way

Quoting Recap

echo "$var"            # expands $var
echo '$var'            # literal $var (no expansion)
echo $'line1\nline2'   # ANSI-C: interprets \n \t \\ \' etc.
echo "It's a \"test\"" # escape double quotes inside double quotes
word=$'foo\tbar'       # tab embedded in variable

Substrings — Slicing

str="Hello, World"

echo ${str:0:5}        # "Hello"     (from 0, length 5)
echo ${str:7}          # "World"     (from index 7 to end)
echo ${str: -5}        # "World"     (last 5; space before - required)
echo ${str: -5:3}      # "Wor"       (3 chars starting 5 from end)
echo ${str:0:-6}       # "Hello,"    (everything except last 6)

Prefix and Suffix Removal

path="/usr/local/bin/bash"

echo ${path#/}          # remove shortest prefix matching /   → "usr/local/bin/bash"
echo ${path##*/}        # remove longest  prefix matching */  → "bash"
echo ${path%/*}         # remove shortest suffix matching /*  → "/usr/local/bin"
echo ${path%%/*}        # remove longest  suffix matching /*  → "" (empty)

url="https://example.com/page"
echo ${url#*//}         # "example.com/page"
echo ${url##*/}         # "page"

file="archive.tar.gz"
echo ${file%%.*}        # "archive"   (strip all extensions)
echo ${file#*.}         # "tar.gz"    (everything after first dot)
echo ${file##*.}        # "gz"        (everything after last dot)

Pattern Substitution

str="the cat sat on the mat"

echo ${str/the/a}       # replace FIRST "the" → "a cat sat on the mat"
echo ${str//the/a}      # replace ALL   "the" → "a cat sat on a mat"
echo ${str/#the/a}      # replace only if at START of string
echo ${str/%mat/rug}    # replace only if at END of string

# Delete by substituting empty string
echo ${str//the/}       # " cat sat on  mat"
echo ${str// /_}        # "the_cat_sat_on_the_mat"

# Patterns support globbing (* ? [...])
echo ${str//[aeiou]/}   # remove all vowels → "th ct st n th mt"

Case Conversion (Bash 4+)

str="Hello World"

echo ${str,,}           # all lowercase:  "hello world"
echo ${str^^}           # all uppercase:  "HELLO WORLD"
echo ${str,}            # first char lower: "hello World"
echo ${str^}            # first char upper: "Hello World"

# With a pattern (only chars matching the pattern are converted)
echo ${str^^[aeiou]}    # uppercase vowels: "hEllO wOrld"
echo ${str,,[A-Z]}      # not useful alone, but valid syntax

String Comparison

[[ "$a" == "$b" ]]      # equal
[[ "$a" != "$b" ]]      # not equal
[[ "$a" < "$b" ]]       # lexicographic less-than (inside [[ ]])
[[ "$a" > "$b" ]]       # lexicographic greater-than
[[ -z "$a" ]]           # true if $a is empty
[[ -n "$a" ]]           # true if $a is non-empty

# Glob matching inside [[ ]]
[[ "$file" == *.txt ]]          # matches *.txt glob
[[ "$file" != *.bak ]]

# Regex matching (=~ only in [[ ]])
[[ "$str" =~ ^[0-9]+$ ]]        # matches digits only
[[ "$email" =~ @.*\. ]]         # loose email check

Searching and Testing Strings

# Contains substring (using glob)
if [[ "$str" == *"needle"* ]]; then
  echo "found"
fi

# Contains substring (using case)
case "$str" in
  *needle*) echo "found" ;;
  *)        echo "not found" ;;
esac

# Index of substring (no built-in; use expr or awk)
expr index "$str" "World"       # position (1-based) or 0

# grep for contains check
if echo "$str" | grep -q "needle"; then echo "found"; fi

String Splitting

str="one:two:three"

# Split on delimiter using read
IFS=':' read -ra parts <<< "$str"
echo "${parts[0]}"   # one
echo "${parts[1]}"   # two
echo "${parts[@]}"   # one two three

# Split and iterate
IFS=',' read -ra items <<< "a,b,c,d"
for item in "${items[@]}"; do
  echo "$item"
done

# Temporarily change IFS in a loop
old_IFS=$IFS
IFS=':'
for part in $str; do echo "$part"; done
IFS=$old_IFS

Here Strings and Here Documents

# Here-string: redirect a string to stdin
grep "foo" <<< "foo bar baz"
wc -w <<< "hello world"
read first second <<< "one two three"

# Here-document: multi-line stdin
cat <<EOF
Line 1
Line 2 with $var
EOF

# Quoted heredoc: no expansion
cat <<'EOF'
Literal $var here
No $(substitution) either
EOF

# Indented heredoc (Bash 4+, strip leading tabs)
cat <<-EOF
	Indented content
	More content
	EOF

printf for String Formatting

printf "%s\n" "hello"                # simple string
printf "%-20s %5d\n" "item" 42       # left-align string, right-align int
printf "%020d\n" 42                  # zero-padded: 00000000000000000042
printf "%.3f\n" 3.14159              # float: 3.142
printf "%x\n" 255                    # hex: ff
printf "%o\n" 8                      # octal: 10
printf "%05.1f\n" 3.14               # 003.1
printf "%q\n" "hello world"          # shell-quoted: 'hello world'
printf -v myvar "Hello, %s" "world"  # store in variable (no subshell)

String Manipulation with External Tools

# tr — transliterate or delete characters
echo "Hello" | tr '[:lower:]' '[:upper:]'   # HELLO
echo "Hello World" | tr -d ' '              # HelloWorld
echo "hello" | tr -s 'l' 'L'               # heLo
echo "a1b2c3" | tr -dc '[:alpha:]'         # abc (delete non-alpha)

# sed — stream editor
echo "foo bar" | sed 's/foo/baz/'          # baz bar
echo "foo foo" | sed 's/foo/baz/g'         # baz baz
echo "hello world" | sed 's/\(.\)/\1\n/g' | head -5

# awk — field extraction
echo "Alice 30 NYC" | awk '{print $2}'     # 30
echo "a:b:c" | awk -F: '{print $NF}'      # c (last field)

# cut — simple field extraction
echo "a:b:c" | cut -d: -f2                # b
echo "hello" | cut -c1-3                  # hel

Special String Patterns and Tricks

# Trim whitespace (Bash, no external tools)
str="   hello   "
trimmed="${str#"${str%%[![:space:]]*}"}"    # trim leading
trimmed="${trimmed%"${trimmed##*[![:space:]]}"}"  # trim trailing

# Or with parameter expansion + xargs
echo "  hello  " | xargs

# Check if string is a number
[[ "$str" =~ ^-?[0-9]+$ ]] && echo "integer"
[[ "$str" =~ ^-?[0-9]*\.?[0-9]+$ ]] && echo "number"

# String multiplication (repeat)
printf '%0.s-' {1..40}     # 40 dashes

# Multiline string in variable
text=$(printf 'line1\nline2\nline3')
IFS=$'\n' read -rd '' -a lines <<< "$text"
echo "${lines[1]}"          # line2