Extract substring in Bash
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Bash can slice strings directly with parameter expansion, so you usually do not need cut, awk, or expr for simple substring work. The built-in syntax is faster, easier to read once you know the rules, and portable across normal Bash environments.
Slice by Offset and Length
The basic form is variable:offset:length inside parameter expansion. Offsets are zero-based, so position 0 means the first character.
The output is:
If you omit the length, Bash returns everything from the offset to the end.
That prints ready.
This form is good when the string format is fixed, such as a prefix, a date stamp, or a known identifier layout.
Use Negative Offsets Carefully
Bash also supports counting backward from the end of the string. The common detail people miss is the space before a negative offset.
That returns gz.
You can combine a negative offset with a length as well.
That prints tar.
The spacing matters because without it Bash can interpret the expression differently. If you find the syntax hard to scan, assign the string to a named variable first and keep the slice simple.
Pattern Removal Often Solves the Real Problem
Not every extraction job should use character positions. When strings are structured by delimiters, Bash pattern removal is often safer.
This uses two different operators:
- '
##removes the longest matching prefix' - '
%removes the shortest matching suffix'
For file names, URLs, and extension handling, pattern removal is usually more maintainable than hard-coded indexes. If the length of the directory path changes, the pattern version still works.
Extract from Script Input
A common real-world case is taking part of a positional argument. The safest pattern is to copy the argument into a normal variable and slice that variable.
This keeps the script readable and avoids confusion around special parameter behavior. It also makes it easier to add validation, such as checking that the argument is long enough before slicing.
Compare Built-Ins with External Tools
Older shell examples often call external commands for substring extraction.
This works, but it starts another process. In a tiny script that does not matter much, but inside loops or frequently called helpers, built-in expansion is cleaner and faster.
Use an external command only when the operation is no longer simple slicing. For example, field-based parsing with a delimiter may be better served by cut -d, and complex reshaping may be better served by awk.
Quote the Result
Substring extraction does not remove the need for quoting. If the extracted value contains spaces or wildcard characters, unquoted expansion can trigger word splitting or pathname expansion.
Keep the expansion quoted unless you explicitly want shell splitting behavior.
Common Pitfalls
- Forgetting that Bash offsets are zero-based and slicing one character too early or too late.
- Writing a negative offset without the required space, as in
${var: -3}. - Using fixed numeric positions when the underlying data is really delimiter-based and better handled with
%,%%,#, or##. - Calling
cutorexprfor ordinary Bash slicing and making scripts noisier than they need to be. - Expanding the extracted value unquoted and introducing word-splitting bugs.
Summary
- Use Bash parameter expansion for most substring tasks.
- '
${var:offset:length}is the standard slicing form.' - Omitting the length returns the remainder of the string.
- Negative offsets work, but the spacing is easy to get wrong.
- Pattern removal operators are often better than numeric slicing for structured strings.

