0

I need to use sed to replace everything before matching pattern with another string in a file

There are various paths in my file. Last few components of those paths are the same irrespective of the user, however, the first few components will change.

For e.g. For user 1, the file contains the following path

build:
   - "/Users/user1/Projects/Stash/sdk/license.txt"

For user 2, the path could be

build:
   - "/Users/user2/Documents/Work/sdk/license.txt"

The last 2 components are i.e. "/sdk/license.txt" are the same for every user.

I want to replace everything before these components with the path provided by the user as it is specific to that user. How to use sed to perform this kind of substitution? I am using a Perl script for the same.

4
  • 1
    can you share the expected output...
    – Siva
    Aug 28 '18 at 4:32
  • Is that a fixed pattern, i.e. always "/sdk/license.txt"? The why not use that, prefixed by the user specific string, overwriting the entire line?
    – RudiC
    Aug 28 '18 at 9:00
  • @SivaPrasath If I pass the path as "/Users/Neeraj/project", the desired output is build: - "/Users/Neeraj/project/sdk/license.txt" Aug 29 '18 at 13:51
  • @RudiC the pattern is fixed. I had thought about the approach you are suggesting but I need to keep a reference to the part that will be replaced so that I can use it later to reset the file Aug 29 '18 at 13:58
1

You can simply use backreferences

sed -e 's/\(^[ ]*\- "\)\(.*\)\(\/sdk\/license\.txt"$\)/\1path_with_which_to_be_replaced\3/'

Here

\(....\) is used to group match and saving it for future use , to use in replacement, you can use \1 \2 as variable name .

So, in your requirement , I break the line in three groups

\(^[ ]*\- "\) for space - "

\(.*\) for part to be replaced, e.g /Users/user2/Documents/Work

\(\/sdk\/license\.txt"$\) for same part i.e. sdk/license.txt"

7
  • 1
    If you enable extended regular expressions, and use a different delimiter for the s/// command, you can remove most of those backslashes: sed -r -e 's,(^ *- ")(.*)(/sdk/license\.txt"$),\1path_with_which_to_be_replaced\3,' Aug 28 '18 at 14:56
  • And, assuming there are no spaces in the directory path (a big assumption), you can capture less: sed -r -e 's,"[^[:blank:]]*(/sdk/license\.txt"$),"path_with_which_to_be_replaced\1,' Aug 28 '18 at 14:57
  • But perl's look-arounds are helpful here: perl -pe 's{(?<=").*?(?=/sdk/license.txt)}{replacement-text}' Aug 28 '18 at 15:00
  • @glennjackman The Perl look-around you suggested worked for me perfectly. Thank you so much. The -r option for sed is not available on macOS. Hence I am not able to verify the sed commands you have provided. Aug 29 '18 at 14:25
  • @mkmayank The sed command you have provided doesn't seem to work for me. It doesn't substitute anything in my case Aug 29 '18 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.