1

There are two files:

file1:

dir='/root/path/to/somewhere/'
sed -zre "s|dir=(.*)'$|dir='$(echo $dir)'|g" -i file2

file2:

dir='/blah/blah/'

I want to do this:

find a line having dir=(.*) and replace with the value of $dir

I run bash file1, but it doesn't replace anything in `file21.

Saeed
  • 3,255
  • 4
  • 17
  • 36
  • 1
    Your `file1` is essentially a shell script. Add `#!/bin/bash` as the first line and `chmod +x file1` so you just just run it like `./file1`. .. It seems like your `sed` should work, but I have to leave to meet my wife. So I'm sure others will help. Good luck. – shellter Jun 04 '23 at 17:07
  • 2
    `$(echo $dir)` can be just `$dir` – anubhava Jun 04 '23 at 17:09
  • @shellter it is a bash file and I think it has nothing to do with shebang. I run `bash file1` which is the same as yours. Have great night BTW. – Saeed Jun 04 '23 at 17:12
  • @anubhava I tried but didn't change – Saeed Jun 04 '23 at 17:12
  • 1
    Try: `sed -i "s|dir=.*|dir='$dir'|" file2` – anubhava Jun 04 '23 at 17:17
  • 1
    this command will delete everything following the `dir` assignment, if that is not the final line in the input. Consider `seq 10 | sed -zre 's/5.*/also deletes 6 through 10/g'`. Contrast: `seq 10 | sed -zre 's/5[^\n]*/change one line/g'`. Also `/g` flag serves no purpose here. – jhnc Jun 04 '23 at 17:22
  • @anubhava would you please write it as answer? – Saeed Jun 04 '23 at 17:24
  • 1
    @jhnc what anubhava commented worked. Thanks for the comment and method. – Saeed Jun 04 '23 at 17:25
  • 1
    The other problem is that `-z` changes the meaning of `$` - it no longer matches end of line – jhnc Jun 04 '23 at 17:26
  • 2
    I found your original title confusing and wasn't sure if you understood you have a shell script in `file1`. Kudos for improving your question. Glad you have an answer! Good luck to all! – shellter Jun 04 '23 at 17:55
  • 1
    You're probably going to run into problems trying to use sed for that without escaping metachars, see [is-it-possible-to-escape-regex-metacharacters-reliably-with-sed](https://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed). FWIW I'd use awk instead since awk understands literal strings. – Ed Morton Jun 04 '23 at 18:56
  • 1
    I don't see the point in using `echo`: Your string is within doule quotes, and the shell will expand `$dir` to the content of the variable. The _echo_ would just add a newline character and replace a run of spaces in the variable `dir` by a single space. A more serious problem is your _sed_ pattern. Since all 4 characters in _(.*)_ are interpreted as regex characters, you need to escape them if you want to treat them literally. – user1934428 Jun 05 '23 at 06:19

1 Answers1

2

Following sed should work for you:

sed -i "s|dir=.*|dir='$dir'|" file2

Note removal of incorrect options -zre in this command and removal of redundant command substitution from your sed command.

Specifically problematic is use of -z that slurps complete input file in a single line of text thus failing to match '$ since closing single quote is not the last character in file.

If you want to avoid repeating dir= 2 times then use a capture group:

sed -E -i.bak "s|(dir=).*|\1'$dir'|" file2
anubhava
  • 761,203
  • 64
  • 569
  • 643