Table of Contents
Using Parameter Expansion
Use parameter expansion to get everything after character in Bash.
1 2 3 4 5 6 |
string="Hello World!" delimiter=" " output="${string#*$delimiter}" echo "$output" |
1 2 3 |
World! |
First, we set the string
variable with a string type value; then, we initialised the delimiter
variable with a space character (" "
). The delimiter
variable contained the character, after which we wanted to extract the remaining portion of the string
.
After that, we used the parameter expansion as "${string#*$delimiter}"
to get everything after the delimiter
. Here, the #
signified the removal of the shortest match of the *$delimiter
from the starting of a value stored in string
.
In this case, the *$delimiter
matched any characters, followed by the delimiter
(a space character). So, the portion of the string
matched by the *$delimiter
was removed, leaving everything after the specified delimiter, which we stored in the output
variable. Finally, we used echo
to display output
on the Bash console.
Let’s see another example where the delimiter
occurs multiple times.
1 2 3 4 5 6 |
string="Hello World! How is it going?" delimiter=" " output="${string#*$delimiter}" echo "$output" |
1 2 3 |
World! How is it going? |
if you want to get everything after last occurrence of the character, use output="${string##*$delimiter}"
.
1 2 3 4 5 6 |
string="Hello World! How is it going?" delimiter=" " output="${string##*$delimiter}" echo "$output" |
1 2 3 |
going? |
Alternatively, specify the starting index of the portion you want to retrieve; see the following example.
1 2 3 4 |
string="Hello World! How is it going?" echo "${string:6}" |
1 2 3 |
World! How is it going? |
It used a 0-based index system.
Using cut
Command
Use the cut
command to get everything after the specified character in Bash.
1 2 3 4 5 6 |
string="Hello World!" delimiter=" " output=$(echo "$string" | cut -d "$delimiter" -f2-) echo "$output" |
1 2 3 |
World! |
After initialising the string
and delimiter
variables, we used the substitution to grab the command’s output enclosed within the $(...)
and assigned it to the output
variable. How this substitution worked, let’s understand it below:
The echo
command printed the value of the string
variable. Here, it did not mean to display on the console but pass the value of the string
variable to the next command, the cut command.
The cut
is a command-line utility to extract everything after the delimiter
from the string
. While using cut
, the -d "$delimiter"
specified the delimiter to be used; in the above example, we used a space character as a delimiter.
The -f2-
option chooses the sections (fields) beginning from the second field and onwards. What was the second field here? In the cut
command, the fields/sections are typically defined by the given delimiter character, and the -f
is used to mention which field(s) needs to be extracted.
Here, the -f2-
specified that we wanted to extract all fields starting from the second field. For example, the cut
command used the delimiter
(a space character) to split the string
("Hello World"
) into fields based on the delimiter. Hello
was the first field, while World
was the second.
So, the -f2-
indicated to capture all the fields starting from the second field. Finally, we used the echo
command to display the value of the output
variable on the console.
Let’s see another example to clarify the concepts using the cut
command to get everything after the character.
1 2 3 4 5 6 |
string="Hello World! How is it going?" delimiter=" " output=$(echo "$string" | cut -d "$delimiter" -f2-) echo "$output" |
1 2 3 |
World! How is it going? |
See, the cut
command splits the string
based on the delimiter
and grabs the second field and onwards.
The
cut
command splits the input string into fields based on the given delimiter. When the delimiter occurs multiple times in the string, thecut
command treats every occurrence as a separate delimiter and extracts the corresponding fields accordingly.
Using awk
Command
Use the awk
command to get everything after the specified character in Bash.
1 2 3 4 5 6 |
string="Hello World!" delimiter=" " output=$(echo "$string" | awk -F "$delimiter" '{print $2}') echo "$output" |
1 2 3 |
World! |
This example resembles the first example in the previous section, but we used the awk command this time. The awk
split the string
based on the given delimiter
and then printed the second field. Here, -F
was used to specify the field separator, the delimiter
variable.
The {print $2} instructed the awk
command to print the second field of every input line. Note that the fields in awk
are identified by their positions; for instance, $1
represents the first field, $2
indicates the second field and so on.
The above code snippet will not work if the delimiter occurs multiple times in the input string.
Let’s see another example of the string
will have multiple occurrences of the delimiter
.
1 2 3 4 5 |
string="Hello World! How is it going?" delimiter=" " output=$(echo "$string" | awk -F "$delimiter" '{for (i=2; i<=NF; i++) printf "%s%s", $i, (i<nf echo></nf> |
1 2 3 |
World! How is it going? |
In the above example, we only modified the awk
code block and used a for
loop to iterate through every field, from the second field (i=2
) to the last field represented by the NF
. We used %s%s
in the printf
statement to join the fields inside the loop. Note that the $i
denoted the i-th
field’s value in the input record.
While the (i<NF?" ":ORS)
was used to append a space character between the fields, excluding the last field where the ORS
(Output Record Separator, typically a newline character) was used instead.
Using sed
Command
Use the sed
command to get everything after the specified character in Bash.
1 2 3 4 5 6 |
string="Hello World!" delimiter=" " output=$(echo "$string" | sed "s/.*$delimiter//") echo "$output" |
1 2 3 |
World! |
This code snippet is similar to those using the cut
and awk
commands. Here, we used the sed command, which performed the substitution operation (s/.*$delimiter//
). The .*$delimiter
pattern matched any character (.*
) followed by a delimiter ($delimiter
). We replaced the matched pattern with an empty string (//
) to remove everything, including the delimiter.
Will the above script work if the delimiter occurs multiple times in the input string? NO. See the following example to learn how we can do that.
1 2 3 4 5 6 |
string="Hello World! How is it going?" delimiter=" " output=$(echo "$string" | sed "s/[^$delimiter]*$delimiter//") echo "$output" |
1 2 3 |
World! How is it going? |
You are right; we only changed the sed
expression. In this expression, the [^$delimiter]*
matched any sequence of the characters that are not the delimiter, while the $delimiter
matched the delimiter itself. Again, we replaced the matched portion with the empty string (//
) to remove everything up to and including the delimiter.
Using grep
Command
Use the grep
command to get everything after the character in Bash.
1 2 3 4 5 6 |
string="Hello World!" delimiter=" " output=$(echo "$string" | grep -oP "(?<=${delimiter}).*") echo "$output" |
1 2 3 |
World! |
This code fence also resembled the examples using cut
and awk
commands, initialising the string
and delimiter
variables with a string value and a space character, respectively. Then, we used the substitution syntax represented by $(...)
to capture the pipeline output enclosed within this syntax (see the above code).
In this substitution syntax, we used the echo
command to pass the value of the string
variable to the grep command. The grep
(Global Regular Expression Print) command is a command-line utility for pattern matching and searching within the input streams. We used the grep
command with the following options:
-o
displayed the matching portions of a line.-P
enabled the Perl-compatible regex (regular expressions)."(?<=${delimiter}).*"
regex pattern used the positive lookbehind ((? In regular expressions, a positive look-behind is a construct which lets you match the given pattern only if another pattern precedes it. The positive look-behind's syntax is
(?<=…), where
…` represents the pattern that should occur before the desired match.
Similarly, you can use the grep
command with the same regex to get everything after the character where the specified character occurs multiple times. See the following example.
1 2 3 4 5 6 |
string="Hello World! How is it going?" delimiter=" " output=$(echo "$string" | grep -oP "(?<=${delimiter}).*") echo "$output" |
1 2 3 |
World! How is it going? |
Further reading:
Using expr
Command
Use the expr
command to get everything after the character in Bash.
1 2 3 4 5 6 7 8 9 |
string="Hello World!" delimiter=" " delimiter_index=$(expr index "$string" "$delimiter") start_index=$((delimiter_index + 1)) charLength=$(expr length "$string") output=$(expr substr "$string" $start_index $charLength) echo "$output" |
1 2 3 |
World! |
Here, we used the expr command. Note that we used nested expr
, which means the inner expr
would be evaluated first. So, we used the expr
command with index
function as expr index "$string" "$delimiter"
to find the index of the first occurrence of the delimiter
within the string
, which we captured using $(...)
and stored in delimiter_index
variable.
After that, we added 1
to the delimiter_index
and stored it in start_index
. Why did we add 1
? Because we want to get everything after the delimiter, excluding the delimiter itself.
Then, we used the expr
command with length
function as expr length "$string"
to calculate the length of the string
and returned the number of characters in the given string (string
), which we grabbed using $(...)
and stored in the charLength
variable.
Finally, we used the expr
command with substr
function as expr substr "$string" $(expr index "$string" "$delimiter") $(expr length "$string")
to extract a substring from the original string, which was the value of string
in our case. It took the following three arguments:
- Original string (
$string
). - The starting position of a substring.
- The substring’s length.
Again, we used the $(...)
to capture the output of the previous expr
command and assigned it to the output
variable, which was further used with the echo
command to display its value on the Bash console.
Similarly, we can use the expr
command with a string where the specified delimiter occurs multiple times.
1 2 3 4 5 6 7 8 9 |
string="Hello World! How is it going?" delimiter=" " delimiter_index=$(expr index "$string" "$delimiter") start_index=$((delimiter_index + 1)) charLength=$(expr length "$string") output=$( expr substr "$string" $start_index $charLength) echo "$output" |
1 2 3 |
World! How is it going? |
Using the IFS
Variable and read
Command
Use the IFS
variable (a shell variable) and read
command to get everything after the character in Bash.
1 2 3 4 5 6 7 |
string="Hello World!" delimiter=" " IFS="$delimiter" read -ra portions <<< "$string" output="${portions[1]}" echo "$output" |
1 2 3 |
World! |
Again, we initialised the string
and delimiter
variables with a string-type value and a space character, respectively. Then, we set the IFS
variable (a shell variable) to the value of delimiter
as IFS="$delimiter"
, which determined the field separator for the read
command.
After that, the read -ra portions
read the input (string
), which was passed to it using the herestring (<<<
) operator, and stored the separated fields into the portions
array. Here, -a
was used to instruct the read
to store the values into an array, while -r
preserved any backslashes in the input.
Finally, we assigned the second element located at index 1
of the portions
array to the output
variable, which was further used with echo
to display on the Bash console.
What if the input string contains multiple occurrences of the delimiter? Explore the following example to see what modifications are required.
1 2 3 4 5 6 7 |
string="Hello World! How is it going?" delimiter=" " IFS="$delimiter" read -ra portions <<< "$string" output="${portions[*]:1}" echo "$output" |
1 2 3 |
World! How is it going? |
Everything is similar to the last example, excluding the way of extracting values from the portions
array. In the "${portions[*]:1}"
, the ${portions[*]}
joined all the array elements into a single string.
However, the :1
specified that we wanted to grab everything after the first element of the array, which effectively removed the first part of the string. As a result, the output
contained everything after the specified character, the value of the delimiter
.
That’s all about how to get everything after Character in Bash.