The good news is that your substitution is already written to "match left to right and capture everything right of match"! But there are two things to keep in mind about your current code not working.
First, the match you asked for before the group in parentheses is .*
. .
matches any character and *
matches zero-or-more occurrences. So the code matches zero-or-more occurrences of any character. But how many occurrences is zero-or-more?
That's affected by the second thing. By default, matches are greedy: they match as many characters as they can without causing the match to fail. In this case, they can match everything up to the last underscore (the one before the final 1
.)
You can fix your pattern to match just a single character: .
without the *
:
echo "a_4_3_2_1" | sed 's/.\(_.*\)/\1/'
_4_3_2_1
Some tools allow use of a minimal match, which would make the match non-greedy. But not sed
.