I am trying to search and replace a url present in source code of html/css files in target folder and subfolders. I have tried to use the following command :

find . -type f | xargs sed -i  's/https\:*\.websitedomain\.fr\///g'

What i am i missing ?

Thanks in advance for any advice

  • 2
    Please edit your question and add more details: What files do you have? Show example input file contents, actual result and expected result.
    – Bodo
    Jun 1 '21 at 14:54
  • I'm not sure what your trying to do, but itloks like your sed command is wrong. What are you truing to accomplish?
    – Shōgun8
    Jun 1 '21 at 15:04
  • If * in your pattern is meant as "any number of characters" like in file globbing, then you have to use .* instead. To avoid matching \.websitedomain\.fr\/ in the file or argument part of an URL I suggest to use [^/]* (any number of any characters but /) instead.
    – Bodo
    Jun 1 '21 at 15:25

Assuming a GNU system (which your usage of sed -i suggests is the case for you):

find . -type f -exec grep -lZEe "$eregex" {} + |
  xargs -r0 sed -i -E "s|$eregex||g"

Some of the problems in your approach:

  • the main one is that the * regexp operator matches 0 or more of the previous atom, so :* matches 0 or more :s. Here we're replacing it with [^/[:space:]]+ which is 1 or more (+, an extended regex operator, hence the -Es) characters other than whitespace and / (.* which is probably what you had in mind could end up matching google.com/ and foo in https://google.com/ and foo.websitedomain.fr/file for instance).
  • The output format of find -print (one file path per line) is not compatible with the expected input format of xargs (expects blank or newline separated, possibly quoted words). The output format of find -print is not post-processable reliably, it should only be used for human consumption. Better to use find ... -exec cmd {} +, and/or use NUL-delimited records with xargs -r0 (-r and -0 being GNU extensions).
  • sed -i replaces the files with a modified copy of the original, with possible loss of metadata information, so it's best to avoid running on files that are not going to be modified, hence the use or grep -lZ to get a list (NUL delimited with -Z so it can be used by xargs -0) of files with at least one line matching the regex.
  • : is not a regexp operator so doesn't need to be escaped. What \: matches is unspecified by POSIX and undocumented in most sed implementations. So while currently it may match on a : in your sed implementation, that may change in the future (like \< or \w while originally matching on < and w respectively ended up matching a word boundary and word character in newer versions).
  • if your regexp or replacement in sed's s command contains a /, it's easier to use a different character as the delimiter than having to escape / with backslashes which makes it quite hard to read. Hence s|regexp|replacement|g here instead of s/regexp/replacement/g. I do like | as it makes for legible code. It has the disadvantage that it can't be used in ex/vi's s/regex/replacement/ though as | separates ex commands there (it's also an extended regex operator).

Try this:

find . -type f | xargs sed -i  's/test\.com/set\.com/g' 

If you need to test for the inclusion of https then try this:

find . -type f | xargs sed -i  's/https\:\\\\test\.com/https\:\\\\set\.com/g' 

NOTE*: this replaces test.com with set.com

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.