Practical examples of string manipulation in shell scripts: 3 examples that actually matter

If you write shell scripts for anything beyond toy projects, you spend a lot of time pushing strings around: parsing filenames, cleaning logs, validating input, and gluing tools together. That’s where good **examples of string manipulation in shell scripts: 3 examples** and several bonus ones can save you hours of trial and error. In this guide, we’ll walk through real examples of string manipulation in shell scripts that you’d actually use at work: trimming, slicing, replacing, pattern matching, and a bit of regex with `grep` and `sed`. We’ll keep everything POSIX‑friendly where it makes sense, but I’ll also show a few Bash‑specific tricks that are worth knowing in 2024. By the end, you’ll not only have three core examples of string manipulation in shell scripts, you’ll also see multiple variations and real examples pulled from common DevOps, data cleanup, and automation tasks. No theory for theory’s sake—just practical shell snippets you can drop into your next script.
Written by
Jamie
Published

3 headline examples of string manipulation in shell scripts

Let’s start with three best examples of string manipulation in shell scripts that show up constantly in real automation:

  • Cleaning and normalizing user input
  • Parsing filenames and paths
  • Extracting fields from log lines or command output

Each of these “3 examples” will include multiple smaller variations, so you can adapt them to your own scripts.


Example 1: Cleaning and normalizing user input

This is the first core example of string manipulation in shell scripts you’ll use in almost every interactive script: taking messy user input and turning it into something predictable.

Trim whitespace and collapse weird spacing

Users copy‑paste. Terminals add stray spaces. Your script should handle it.

#!/usr/bin/env bash

read -r -p "Enter environment (dev / stage / prod): " env

## 1) Trim leading/trailing whitespace using parameter expansion
trimmed_env=${env##[[:space:]]*}   # remove leading space pattern
trimmed_env=${trimmed_env%%[[:space:]]*} # remove trailing space pattern (simple case)

## More reliable approach using xargs (portable)
normalized_env=\((printf '%s' "\)env" | xargs)

echo "Raw: [$env]"
echo "Normalized: [$normalized_env]"

In practice, I usually combine this with case normalization.

Force lowercase or uppercase for predictable comparisons

bash gives you convenient case conversion operators:

#!/usr/bin/env bash

read -r -p "Enable feature? (YES/yes/No/no): " answer

## Convert to lowercase for comparison
answer_lc=${answer,,}   # Bash-specific; for POSIX, use tr

if [[ \(answer_lc == "yes" || \)answer_lc == "y" ]]; then
  echo "Feature enabled"
else
  echo "Feature disabled"
fi

POSIX‑style alternative:

answer_lc=\((printf '%s' "\)answer" | tr 'A-Z' 'a-z')

This is one of the most common examples of string manipulation in shell scripts: 3 examples often start with exactly this pattern—trim, normalize, compare.

Validate input with simple pattern checks

You don’t always need heavy regex libraries. Basic shell patterns go pretty far:

#!/usr/bin/env bash

read -r -p "Enter a 3-letter country code (like USA): " code

case $code in
  [A-Za-z][A-Za-z][A-Za-z])
    echo "Looks valid: $code"
    ;;

  *)
    echo "Invalid code: $code" >&2
    exit 1
    ;;
esac

Here the shell’s pattern matching ([A-Za-z]) serves as another real example of string manipulation in shell scripts that’s clean and fast for simple validation.


Example 2: Parsing filenames and paths (the classic real‑world use case)

The second of our 3 main examples of string manipulation in shell scripts is about filenames. If you ever process batches of files, you’ll recognize these patterns.

Split filename into base name and extension

You’ve got files like report_2024-12-01.csv and you need the base name, the extension, or both.

#!/usr/bin/env bash

file="report_2024-12-01.csv"

## Extract extension
ext=${file##*.}

## Remove extension
base=${file%.*}

echo "File: $file"
echo "Base: $base"
echo "Ext:  $ext"

This ## and % syntax is one of the best examples of shell parameter expansion. It’s fast, built‑in, and avoids calling external tools.

Strip directory path or extract directory name

You might get a full path from find or a config file, and you only want the filename:

path="/var/log/nginx/access.log"

## Remove everything up to the last slash
filename=${path##*/}

## Remove the filename, keep directory path
dirname=${path%/*}

echo "Path:     $path"
echo "Filename: $filename"
echo "Dirname:  $dirname"

Again, no sed, no awk, no cut. Just pure shell. This is a textbook example of string manipulation in shell scripts that works in Bash, Dash, and most POSIX shells.

Add or change an extension for batch renaming

Say you’re converting .txt files to .md and want to keep the same base names:

#!/usr/bin/env bash

for file in *.txt; do
  base=${file%.*}
  new_name="${base}.md"
  echo "Would rename \(file -> \)new_name"
#  # mv -- "\(file" "\)new_name"   # uncomment when confident
done

This is one of those real examples of string manipulation in shell scripts that shows up in migration scripts, build pipelines, and ad‑hoc data cleanup.

Generate timestamped backup filenames

Another practical twist on filename manipulation:

#!/usr/bin/env bash

src="config.yml"

## Portable-ish timestamp: YYYYMMDD_HHMMSS
stamp=$(date +%Y%m%d_%H%M%S)
backup="\({src%.yml}_backup_}\(stamp}.yml"

cp -- "\(src" "\)backup"
echo "Created backup: $backup"

Here we combine parameter expansion with date to create readable, sortable backup names.


Example 3: Extracting and transforming text from logs and command output

The third of our 3 headline examples of string manipulation in shell scripts is log and output parsing. This is where shell really earns its keep.

Extract fields from log lines using cut and parameter expansion

Imagine an Nginx access log line:

203.0.113.42 - - [02/Dec/2025:12:34:56 +0000] "GET /api/users HTTP/1.1" 200 532

You want the IP address and the HTTP method.

#!/usr/bin/env bash

log_line='203.0.113.42 - - [02/Dec/2025:12:34:56 +0000] "GET /api/users HTTP/1.1" 200 532'

ip=${log_line%% *}        # everything before first space

## Extract the quoted request part
request=${log_line#*"}    # remove up to first quote
request=${request%%"*}    # remove from last quote onward

## Get method (first word of request)
method=${request%% *}

echo "IP:     $ip"
echo "Method: $method"

This is a nice compact example of string manipulation in shell scripts that avoids external tools entirely for moderate parsing.

Filter and transform with grep, sed, and awk

Sometimes you do need the classics. Suppose you want all 500‑level errors from a log file and just the endpoint path:

#!/usr/bin/env bash

log_file="/var/log/nginx/access.log"

grep ' 5[0-9][0-9] ' "$log_file" \
  | sed -n 's/.*"[A-Z]\+ \([^ ]\+\) HTTP.*/\1/p'

Explanation in plain English:

  • grep ' 5[0-9][0-9] ' finds lines with HTTP status 500–599.
  • sed uses a regex to capture the request path and print only that.

This is a more advanced real example of string manipulation in shell scripts, combining pattern matching with regex to mine logs.

If you want something more maintainable, awk can be cleaner:

awk '\(9 ~ /^5[0-9][0-9]\)/ { print \(7 }' "\)log_file"

Here \(9 is the status code field and \)7 is the path in a typical combined log format.


Extra real‑world examples of string manipulation in shell scripts

The article promised examples of string manipulation in shell scripts: 3 examples, but in real work you’ll need more patterns. Here are additional, very common ones you’ll actually use.

Environment variable defaults and fallbacks

Config‑heavy scripts often need defaults when a variable is empty.

#!/usr/bin/env bash

## Use existing value if set, otherwise fall back
: "${APP_ENV:=development}"
: "${LOG_LEVEL:=info}"

echo "APP_ENV:   $APP_ENV"
echo "LOG_LEVEL: $LOG_LEVEL"

The ${var:=default} pattern both expands and assigns, giving you a clean way to set defaults without extra if blocks.

Simple search-and-replace in Bash variables

Bash has built‑in substring replacement, which is one of the best examples of string manipulation in shell scripts when you need quick, local edits.

#!/usr/bin/env bash

url="https://api.example.com/v1/users"

## Replace only first occurrence
api_v2=${url/v1/v2}

## Replace all occurrences
no_https=${url//https:/http:}

echo "Original: $url"
echo "v2 URL:  $api_v2"
echo "HTTP:    $no_https"

This is lighter weight than firing up sed for small replacements.

Substring extraction by index and length

For fixed‑width strings (timestamps, IDs, etc.), substring slicing is handy.

#!/usr/bin/env bash

timestamp="20251202T143501Z"  # YYYYMMDDThhmmssZ

year=${timestamp:0:4}
month=${timestamp:4:2}
day=${timestamp:6:2}

printf 'Date: %s-%s-%s\n' "\(year" "\)month" "$day"

This is Bash‑specific, but it’s so common that it’s worth learning. For POSIX shells, you can fall back to cut:

year=\((printf '%s' "\)timestamp" | cut -c1-4)

Sanitizing filenames or IDs

Sometimes you need to strip unsafe characters from user‑supplied strings before using them as filenames.

#!/usr/bin/env bash

raw_name="Project: Q4/2025*Results?"

## Replace everything not alphanumeric, dash, or underscore with underscore
safe_name=\((printf '%s' "\)raw_name" | sed 's/[^A-Za-z0-9_-]/_/g')

echo "Raw:  $raw_name"
echo "Safe: $safe_name"

This is a practical example of string manipulation in shell scripts that can prevent annoying errors and even security issues when dealing with untrusted input.

Parsing simple key=value config files

You’ll see this pattern in many production scripts:

#!/usr/bin/env bash

config_file="app.conf"

while IFS='=' read -r key value; do
#  # Skip comments and empty lines
  [[ \(key =~ ^#|^\) ]] && continue

  key_trimmed=\((printf '%s' "\)key" | xargs)
  value_trimmed=\((printf '%s' "\)value" | xargs)

  echo "Key: [\(key_trimmed], Value: [\)value_trimmed]"

done < "$config_file"

Here, IFS='=' and read give you a clean split, and xargs trims whitespace. It’s another understated but powerful example of string manipulation in shell scripts.


Why these examples still matter in 2024–2025

Even as more teams adopt Python, Go, or Rust for larger systems, shell scripts remain the glue in CI pipelines, container entrypoints, and deployment hooks. If you look at popular open source projects on GitHub in 2024–2025, you’ll still see Bash and POSIX shell used for:

  • Docker entrypoint scripts that parse environment variables and construct command lines
  • Kubernetes job wrappers that modify URLs, tokens, and config files
  • CI jobs (GitHub Actions, GitLab CI, CircleCI) that massage strings from environment variables and tool output

Those are all real examples of string manipulation in shell scripts, just at scale.

If you want to go deeper into shell behavior and quoting rules, the GNU Bash Reference Manual is still one of the best primary sources:

  • Bash manual: https://www.gnu.org/software/bash/manual/bash.html

For broader command‑line literacy (including grep, sed, and awk used in many examples here), the MIT Missing Semester course is excellent:

  • MIT Missing Semester (Shell & Tools): https://missing.csail.mit.edu

And if you care about security when working with untrusted input, the OWASP guidance on command injection is worth a read:

  • OWASP Command Injection: https://owasp.org/www-community/attacks/Command_Injection

FAQ: examples of string manipulation in shell scripts

What are some common examples of string manipulation in shell scripts?

Common examples include:

  • Trimming whitespace from user input before comparison
  • Converting strings to lowercase or uppercase for case‑insensitive checks
  • Splitting filenames into base name and extension using parameter expansion
  • Replacing substrings in variables (for example, changing API versions in URLs)
  • Extracting specific fields from log lines with cut, awk, or shell expansion
  • Sanitizing strings to create safe filenames or IDs

These are all real examples of string manipulation in shell scripts that you can adapt to most automation tasks.

Is it better to use pure shell features or tools like sed and awk?

Use pure shell features (parameter expansion, pattern matching, substring replacement) when they’re readable and sufficient. They’re fast and avoid extra processes. Reach for sed, awk, or grep when:

  • You need regex
  • The parsing logic becomes hard to read with only parameter expansion
  • You’re working with multi‑line or more complex structured text

Most of the best examples of string manipulation in shell scripts combine both: built‑in expansion for simple tasks and external tools for heavy lifting.

Can you give an example of safe string handling in shell scripts?

A good safety‑focused example is sanitizing user input before using it in filenames or commands:

#!/usr/bin/env bash

read -r -p "Enter backup label: " label

safe_label=\((printf '%s' "\)label" | sed 's/[^A-Za-z0-9_-]/_/g')
backup_file="backup_${safe_label}.tar.gz"

tar -czf "$backup_file" /some/data

Here, quoting and sanitization work together to reduce the risk of injection and filesystem errors.

Are these examples portable across different shells?

Most parameter expansion patterns (\({var%pattern}, }\(var##pattern}) are POSIX‑friendly and work in bash, dash, ksh, and zsh in POSIX mode. Bash‑specific features like \({var,,} for lowercase and }\(var:offset:length} slicing won’t work in strictly POSIX shells. If portability is a priority, stick to POSIX patterns and use tools like tr, cut, and sed to fill in the gaps.


If you keep these examples of string manipulation in shell scripts: 3 examples (plus the extra patterns) in your toolkit, you’ll spend less time fighting your shell and more time shipping scripts that actually do what you expect.

Explore More Shell Scripting Snippets

Discover more examples and insights in this category.

View All Shell Scripting Snippets