0

For integration tests, I have output that contains full file paths. I want to have my test script replace the user-specific start of the file path (e.g. /Users/uli/) with a generic word (USER_DIR) so that I can compare the files.

The problem, of course, are the slashes in the path. I tried the solutions given here and here, but they don't work for me:

#!/bin/bash

old_path="/Users/uli/"
new_path="USERDIR"

sed -i "s#$old_path#$new_path#g" /Users/uli/Desktop/replacetarget.txt

I get the error

sed: 1: "/Users/uli/Desktop/repl ...": invalid command code u

This is the version of sed that comes with macOS 10.14.6 (it has no --version option and is installed in /usr/bin/, so no idea what exact version).

Update:

I also tried

#!/bin/bash

old_path="/Users/uli/"
old_path=${old_path//\//\\\/}
new_path="USERDIR"
regex="s/$old_path/$new_path/g"

echo $old_path
echo $regex

sed -i $regex /Users/uli/Desktop/replacetarget.txt

But I get the same error. What am I doing wrong?

uliwitness
  • 8,532
  • 36
  • 58
  • Does this answer your question? [How to replace strings containing slashes with sed?](https://stackoverflow.com/questions/16790793/how-to-replace-strings-containing-slashes-with-sed) – oguz ismail Oct 31 '19 at 10:40
  • 1
    No, that's the same as my first attempt, it just uses `:` instead of `#`. And the second suggestion is what I tried in my update. Getting the same error messages with those. – uliwitness Oct 31 '19 at 10:44
  • Your first try works OK on my box. This is an Ubuntu one so it probably have something to do with your specific `sed` version. – Poshi Oct 31 '19 at 11:08
  • Yeah, this has to run on macOS out of the box, where sed is likely stuck on the latest GPLv2 version, so it's probably something related to that. Also, macOS will likely use BSD-derived versions of tools so doesn't have most GNU extensions. – uliwitness Oct 31 '19 at 11:39
  • @uliwitness macOS indeed uses the BSD version of `sed`, not any GNU version. – chepner Oct 31 '19 at 17:15

1 Answers1

0

BSD sed requires an argument following -i (the empty string '' indicates no backup, similar to argumentless -i in GNU sed). As a result, your script is being treated as the backup-file extention, and your input file as the script.

old_path="/Users/uli/"
new_path="USERDIR"
sed -i '' "s#$old_path#$new_path#g" /Users/uli/Desktop/replacetarget.txt

However, sed is a stream editor, based on the file editor ed, so using -i is an indication you are using the wrong tool to begin with. Just use ed.

old_path="/Users/uli/"
new_path="USERDIR"
printf 's#%s#%s#g\nwq\n' "$old_path" "$new_path" | ed /Users/uli/Desktop/replacetarget.txt

Obligatory warning: neither editor is parameterized as such; you are simpling generating the script dynamically, which means it's your responsibility to ensure that the resulting script is valid. (For example, if either parameter contains a ;, it had better be escaped to prevent (s)ed from seeing it as a command separator.)

chepner
  • 497,756
  • 71
  • 530
  • 681