Skip to content
Lesson 4 of 14

Step 1 of 5 · Reading · ~3 min

Learn

Strings and Output

Strings

Everything in bash is a string — so "string manipulation" is really "bash manipulation." The tools come in two tiers: parameter expansion (built into the shell, instant) and delegating to programs (tr, cut, sed — the Unix toolbox). Fluency means knowing both and reaching for the built-in first.

Building strings

Concatenation is just adjacency — no operator at all:

first="Ada"
last="Lovelace"
full="$first $last"           # "Ada Lovelace"
greeting="Hello, ${first}!"   # braces mark the name's end before a letter

Quoting recap with teeth: double quotes expand variables, single quotes don't, and the unquoted form word-splits. For building text, double quotes are your default; you're always one filename-with-spaces away from needing them.

Parameter expansion: the built-in toolkit

Bash packs a surprising string library inside ${ }:

s="hello world"

echo "${#s}"           # 11 — length
echo "${s^^}"          # HELLO WORLD — uppercase (bash 4+)
echo "${s,,}"          # hello world — lowercase
echo "${s/world/bash}" # hello bash — replace first match
echo "${s//o/0}"       # hell0 w0rld — replace ALL matches
echo "${s:0:5}"        # hello — substring: offset 0, length 5
echo "${s:6}"          # world — from offset to end

And the pair that powers half of all real scripts — prefix/suffix stripping, tailor-made for file paths:

file="report.tar.gz"
echo "${file%.gz}"     # report.tar   — strip shortest matching suffix
echo "${file%%.*}"     # report       — strip LONGEST matching suffix
echo "${file#*.}"      # tar.gz       — strip shortest matching prefix

Mnemonic that finally makes these stick: on your keyboard, # is left of $ (prefix), % is right (suffix) — single char = shortest match, doubled = longest. ${file%.txt} ("filename without extension") appears in the own-editor run_tests.sh you may have already read.

When the shell isn't enough: pipe to a program

Some jobs want the toolbox (properly introduced with pipes, next chapter — a preview):

echo "$s" | tr 'a-z' 'A-Z'     # uppercase, the portable way
echo "$s" | cut -d' ' -f1      # first space-delimited field
rev <<< "$s"                   # reverse (<<< feeds a string as stdin)

Rule of thumb: expansion for one variable's worth of text, programs for streams of lines. Spawning a process per string operation inside a tight loop is the classic slow-script mistake; expansions are free.

Comparing strings

Equality tests live in [[ ]] (the test construct, starring next chapter):

if [[ "$answer" == "yes" ]]; thenif [[ -z "$s" ]]; then# -z: is it empty?
if [[ "$file" == *.txt ]]; then# pattern match, right side unquoted glob

Quote the variable side, always — an empty unquoted variable vanishes from the line and produces syntax errors that point nowhere.

Your exercise: Greeting Card

Assemble one line out of two values you read in, with exact spacing and punctuation. It is a quoting-and-adjacency drill: every comma, space, ! and full stop lives inside the double quotes, and the variables are interpolated in place. Use ${name} braces anywhere a letter follows the name, so bash knows where the name ends.

When the output is one character off, the bug is inside your quoted string, not in bash -- the same failure mode as SQL string literals, with the same fix: read the expected output and your format side by side, character by character. The two most common misses in the submission log are a dropped full stop at the end and $name written without the $.

Up nextprintf and HeredocsStrings and Output

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…