1

I'm trying to store a string in a variable, then expand that variable in a sed command.

Several of the values I'm going to put in the variable before calling the command will have parentheses (with and without slashes before the left parentheses, but never before the right), new lines and other special characters. Also, the string will have double quotes around it in the file that's being searched, and I'd like to use those to limit only to the string I'm querying.

The command needs to be able to match with those special characters in the file. Using zsh / Mac OS, although if the command was compatible with bash 4.2 that'd be a nice bonus. echoing to xargs is fine too. Also, if awk would be better for this, I have no requirement to use sed.

Something like...

sed 's/"\"$(echo -E - ${val})\""/"${key}.localized"/g' "${files}"

Given that $val is the variable I described above, $key has no spaces (but underscores) & $files is an array of file paths (preferably compatible with spaces, but not required).

Example Input values for $val...

... "something \(customStringConvertible) here" ...

... "something (notVar) here" ...

... "something %@ here" ...

... "something @ 100% here" ...

... "something for $100.00" ...

Example Output:

... "some_key".localized ...

I was using the sed command to replace the examples above. The text I'm overwriting it with is pretty straight forward.

The key problem I'm having is getting the command to match with the special characters instead of expanding them and then trying to match.

Thanks in advance for any assistance.

Mercutio
  • 1,152
  • 1
  • 14
  • 33

1 Answers1

1

awk is better since it provides functions that work with literal strings:

$ val='something \(customStringConvertible) here' awk 'index($0,ENVIRON["val"])' file
... "something \(customStringConvertible) here" ...

$ val='something for $100.00' awk 'index($0,ENVIRON["val"])' file
... "something for $100.00" ...

The above was run on this input file:

$ cat file
... "something \(customStringConvertible) here" ...
... "something (notVar) here" ...
... "something %@ here" ...
... "something @ 100% here" ...
... "something for $100.00" ...

With sed you'd have to follow the instructions at Is it possible to escape regex metacharacters reliably with sed to try to fake sed out.

It's not clear what your real goal is so edit your question to provide concise, testable sample input and expected output if you need more help. Having said that, it looks like you're doing a substitution so maybe this is what you want:

$ old='"something for $100.00"' new='here & there' awk '
    s=index($0,ENVIRON["old"]) { print substr($0,1,s-1) ENVIRON["new"] substr($0,s+length(ENVIRON["old"])) }
' file
... here & there ...

or if you prefer:

$ old='"something for $100.00"' new='here & there' awk '
    BEGIN { old=ENVIRON["old"]; new=ENVIRON["new"]; lgth=length(old) }
    s=index($0,old) { print substr($0,1,s-1) new substr($0,s+lgth) }
' file

or:

awk '
    BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; lgth=length(old) }
    s=index($0,old) { print substr($0,1,s-1) new substr($0,s+lgth) }
' '"something for $100.00"' 'here & there' file
... here & there ...

See How do I use shell variables in an awk script? for info on how I'm using ENVIRON[] vs ARGV[] above.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • 1
    Ed Morton, if you get a chance, could you take a look at https://stackoverflow.com/q/62109999/4522329 ? – Mercutio May 31 '20 at 00:52