29

I need to use the output of a command as a search pattern in sed. I will make an example using echo, but assume that can be a more complicated command:

echo "some pattern" | xargs sed -i 's/{}/replacement/g' file.txt

That command doesn't work because "some pattern" has a whitespace, but I think that clearly illustrate my problem.

How can I make that command work?

Thanks in advance,

Neuquino
  • 11,580
  • 20
  • 62
  • 76

4 Answers4

40

You need to tell xargs what to replace with the -I switch - it doesn't seem to know about the {} automatically, at least in some versions.

echo "pattern" | xargs -I '{}' sed -i 's/{}/replacement/g' file.txt
Weetu
  • 1,761
  • 12
  • 15
11

this works on Linux(tested):

find . -type f -print0 | xargs -0 sed -i 's/str1/str2/g' 
alex
  • 1,757
  • 4
  • 21
  • 32
8

Use command substitution instead, so your example would look like:

sed -i "s/$(echo "some pattern")/replacement/g" file.txt

The double quotes allow for the command substitution to work while preventing spaces from being split.

Steve
  • 1,215
  • 6
  • 11
  • 9
    It's not what was asked. Author could've invented simplified example to better isolate the logic he asked about. Furthermore, this question is visited by the people searching how to use sed inside xargs specifically (because of the question title) and this does not provide answer to that. – wyde19 May 21 '19 at 18:03
  • Also doesn't seem to work e.g. `sed -i "s/$(echo "grep 'A temporary password' /var/log/mysqld.log | grep --line-buffered -oE '.{0,0}localhost:.{0,13}.' | tail -c 13")/replacement/g" ./mysecure.exp` – geoidesic Apr 23 '22 at 18:47
1

This might work for you (GNU sed):

echo "some pattern" | sed 's|.*|s/&/replacement/g|' | sed -f - -i file.txt

Essentially turn the some pattern into a sed substitution command and feed it via a pipe to another sed invocation. The last sed invocation uses the -f switch which accepts the sed commands via a file, the file in this case being the standard input -.

If you are using bash, the here-string can be employed:

<<<"some pattern" sed 's|.*|s/&/replacement/g|' | sed -f - -i file.txt

N.B. the sed separators | and / should not be a part of some pattern otherwise the regexp will not be formed properly.

potong
  • 55,640
  • 6
  • 51
  • 83