Using sed how could I replace two patterns within a larger pattern on a single line?
Given a single line of text I want to find a pattern (Let's call this the outer pattern) and then within that outer pattern replace two inner patterns.
Here's a one line example of the input text:
Z:\source\private\main\developer\foo\setenv.sh(25): export 'FONTCONFIG_PATH'="$WINE_SHARED_SUPPORT/X11/etc/fonts"
In the example above the outer pattern is /^.*\([[:digit:]]+\):/
which should equal Z:\source\private\main\developer\foo\setenv.sh(25):
The two inner patterns are /^[A-Za-z]:/
and /\\/
.
Another way to phrase my question is:
Using sed I know how to perform replacements of a pattern using the s
command, but how do I limit the range of s
command so it only works on the portion of the input string up to the (25):
?
The ultimate result I am trying to get is the line of text is transformed into this:
/enlistments/source/private/main/developer/foo/setenv.sh(25): export 'FONTCONFIG_PATH'="$WINE_SHARED_SUPPORT/X11/etc/fonts"
Best Answer
This command converts your input example to your output example:
If some of your input contains backslashes in the portion after the
/^.*([[:digit:]]+):/
part, then you will have to divide and conquer to prevent those latter backslashes from being replaced.Explanation (steps marked with an asterisk (
[*]
) apply to both commands):h
- copy the line to hold spaces/^.*([[:digit:]]\+)://
- delete the first part of the line from the original in pattern spacex
- swap pattern space and hold spaces/^\(.*([[:digit:]]\+):\).*/\1/
- keep the first part of the line from the copy (discard the last part)s|\\|/|g
- [*
] change all the backslashes to slashes (in the divide-and-conquer version, only the portion in pattern space - the first part of the line - is affected)s|^[^/]*|/enlistments|
- [*
] change whatever appears before the first slash into "/enlistments" - this could be made more selective if neededG
- append a newline and the contents of hold space onto the end of pattern spaces/\n//
- remove the interior newline