Practical examples of string manipulation in shell scripts: 3 examples that actually matter
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.seduses 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.
Related Topics
Practical examples of examples of variables in shell scripting
Examples of Regular Expressions in Shell Scripts: 3 Practical Examples You’ll Actually Use
Practical examples of command-line arguments in shell scripts examples
Practical examples of shell script examples for beginners
Practical examples of working with arrays in shell scripting: 3 examples you’ll actually use
Practical examples of string manipulation in shell scripts: 3 examples that actually matter
Explore More Shell Scripting Snippets
Discover more examples and insights in this category.
View All Shell Scripting Snippets