-1

When I run this command

for file in $sourceDir
do
   sed -i s/$origText/$newText/g $file
done

it gives me this error:

bad flag in substitute command: 'n'
Greenonline
  • 1,851
  • 7
  • 17
  • 23
  • Do the values of $origText or $newText include any / characters? – icarus Oct 16 '21 at 03:57
  • unquoted variables everywhere. even if this worked, it looks like a really good way to trash your file(s). and if $sourceDir is supposed to contain a list of filenames, it really should be an array. Or if it's supposed to be a directory name, iterate over the files in that directory with for file in "$sourceDir"/*. – cas Oct 16 '21 at 04:09

1 Answers1

1

Most likely $origText or $newText contains a / followed by n, but you're using / as the delimiter between regex and replacement. You'd need to escape it or use a delimiter that doesn't occur in your variables. But there are many other characters you'd need to escape.

It would be easier to use perl (where some sed implementations have borrowed that -i non-standard extension from in the first place) that can substitute arbitrary strings more easily.

You may also want to only rewrite the files that do contain the $origText in the first place.

Given you're not quoting your variable but still using a Bourne-like for loop, I assume you're using the zsh shell, then on a GNU system, that should just be:

print -rNC1 -- "$sourceDir"/*(N.) |
  xargs -r0 grep -lZFe "$origText" -- |
  L="$origText" R="$newText" xargs -r0 perl -pi -e '
    s/\Q$ENV{L}\E/$ENV{R}/g' --

If using another POSIX-like shell, you can replace the first print line (assuming $sourceDir doesn't start with -) with:

LC_ALL=C find "${sourceDir%/}/" -maxdepth 1 ! -name '.*' -type f -print0 |

Or the first 2 lines with:

LC_ALL=C find "${sourceDir%/}/" -maxdepth 1 ! -name '.*' -type f \
  -exec grep -lZFe "$origText" -- |