Bash

Extract part of a string using bashcutsplit

27 September 2026 · 5 min read

Extract part of a string using bashcutsplit

In the vast landscape of data processing and automation, the ability to efficiently manipulate text strings is a cornerstone skill for developers, system administrators, and data analysts alike. Whether you’re parsing log files, extracting specific data from configuration files, or simply organizing command-line output, knowing how to extract part of a string using bash/cut/split is indispensable. This guide delves into the powerful command-line tools and native Bash functionalities that make string manipulation not just possible, but elegantly simple. We’ll explore the precision of cut, the versatility of Bash parameter expansion for substring extraction, and the robust capabilities of tools like awk for more complex splitting and pattern matching.

Mastering these techniques enhances your scripting efficiency and empowers you to automate complex data tasks with confidence. From simple character selections to intricate field extractions, we’ll cover the essential methods to tackle any string challenge you encounter. This foundational knowledge is crucial for anyone looking to optimize their workflow and streamline data handling in a Unix-like environment.

Mastering String Extraction with cut

The cut command is a venerable utility designed for extracting sections from each line of files or piped data, primarily based on byte positions, character positions, or delimiters. It’s exceptionally efficient for structured data where fields are consistently separated by a specific character, such as a comma, tab, or space. Understanding cut is fundamental for quick data parsing directly from the command line, making it a go-to for initial data filtering.

To extract part of a string using cut, you typically specify either the delimiter and field number, or the character positions. For instance, if you have a CSV file and want the second column, cut -d',' -f2 is your solution. The -d option specifies the delimiter, and -f specifies the field number. This method is incredibly useful for processing tabular data where each piece of information resides in a distinct column. A common scenario involves extracting usernames from the /etc/passwd file, which uses a colon as a delimiter.

However, cut does have its limitations. It struggles with variable-length delimiters or nested data structures. For example, if your fields are separated by multiple spaces, cut might not behave as expected unless you preprocess the data. Despite this, for straightforward, delimited data, cut offers unparalleled simplicity and speed. According to the GNU Coreutils documentation for cut, its primary design is for selecting portions of lines based on fixed positions or single characters, making it ideal for standard Unix text processing tasks.

  • Delimiter-based extraction: Use -d for the delimiter and -f for field numbers (e.g., cut -d':' -f1,7).
  • Character-based extraction: Use -c for character ranges (e.g., cut -c1-5 for the first five characters).
  • Byte-based extraction: Use -b for byte ranges, particularly useful for multi-byte character sets.

Native Bash String Manipulation: Substring Extraction and Pattern Matching

While external utilities like cut are powerful, Bash itself offers robust native capabilities for string manipulation, often proving more efficient for single variables or simpler tasks as they avoid spawning new processes. When you need to extract part of a string using bash without relying on external commands, parameter expansion is your primary tool. This technique allows for precise control over string segments, enabling you to extract substrings, remove prefixes, or trim suffixes directly within your shell scripts.

To extract a substring in Bash, the most common and efficient method is using parameter expansion: ${variable:offset:length}. This syntax allows you to specify a starting position (offset) and the number of characters to extract (length), providing precise control over string segments without external commands. For instance, if filename="document.txt", then echo ${<b>Question & Answer : </b><br></br><p>I have a string like this:</p> <pre>/var/cpanel/users/joebloggs:DNS9=domain.example </pre> <p>I need to extract the username (joebloggs) from this string and store it in a variable.</p> <p>The format of the string will always be the same with exception of joebloggs and domain.example so I am thinking the string can be split twice using cut?</p> <p>The first split would split by : and we would store the first part in a variable to pass to the second split function.</p> <p>The second split would split by / and store the last word (joebloggs) into a variable</p> <p>I know how to do this in PHP using arrays and splits but I am a bit lost in bash.</p><br></br><p>To extract joebloggs from this string in bash using parameter expansion without any extra processes...</p> <pre>MYVAR="/var/cpanel/users/joebloggs:DNS9=domain.example" NAME=${MYVAR%:*} # retain the part before the colon NAME=${NAME##*/} # retain the part after the last slash echo $NAME </pre> <p>Doesn't depend on joebloggs being at a particular depth in the path.</p> <hr></hr> <p><strong>Summary</strong></p> <p>An overview of a few parameter expansion modes, for reference...</p> <pre>${MYVAR#pattern} # delete shortest match of pattern from the beginning ${MYVAR##pattern} # delete longest match of pattern from the beginning ${MYVAR%pattern} # delete shortest match of pattern from the end ${MYVAR%%pattern} # delete longest match of pattern from the end </pre> <p>So # means match from the beginning (think of a comment line) and % means from the end. One instance means shortest and two instances means longest.</p> <p>You can get substrings based on position using numbers:</p> <pre>${MYVAR:3} # Remove the first three chars (leaving 4..end) ${MYVAR::3} # Return the first three characters ${MYVAR:3:5} # The next five characters after removing the first 3 (chars 4-9) </pre> <p>You can also replace particular strings or patterns using:</p> <pre>${MYVAR/search/replace} </pre> <p>The pattern is in the same format as file-name matching, so * (any characters) is common, often followed by a particular symbol like / or .</p> <p><strong>Examples:</strong></p> <p>Given a variable like</p> <pre>MYVAR="users/joebloggs/domain.example" </pre> <p>Remove the path leaving file name (all characters up to a slash):</p> <pre>echo ${MYVAR##*/} domain.example </pre> <p>Remove the file name, leaving the path (delete shortest match after last /):</p> <pre>echo ${MYVAR%/*} users/joebloggs </pre> <p>Get just the file extension (remove all before last period):</p> <pre>echo ${MYVAR##*.} example </pre> <p><em>NOTE:</em> To do two operations, you can't combine them, but have to assign to an intermediate variable. So to get the file name without path or extension:</p> <pre>NAME=${MYVAR##*/} # remove part before last slash echo ${NAME%.*} # from the new var remove the part after the last period domain </pre>