1

I want to exchange an unknown hash to a known one in a file. Lot's of escaping needed...

An example for the line to replace:

define( 'PB_PASSWORD', 'ab57a5449b0781c91c4701ab6258655d' );

The target might be:

define( 'PB_PASSWORD', '438bb1dc13ec5cbdf3b938e4fc6c3748' );

This should be done in a linux shell script. I got this far with sed:

sed -i 's/define\( \'PB_PASSWORD\', \'[^“]*\' \);/define\( \'PB_PASSWORD\', \'438bb1dc13ec5cbdf3b938e4fc6c3748\' \);/' todo.txt

But all this does is give me an input

>

I tried several ways to achieve this and I think it's the escaping that keeps me from reaching my goal.

What am I doing wrong?

Barmar
  • 741,623
  • 53
  • 500
  • 612
Joker
  • 51
  • 1
  • 6
  • You have curly quotes inside the `[^...]`. Is that what you intended? – Barmar Jan 19 '23 at 12:33
  • You can avoid much of the escaping if you wrap the argument in double quotes instead of single quotes. – Barmar Jan 19 '23 at 12:33
  • 1
    @Barmar Just using double quotes won't help, escaping is also off here (ERE used while the BRE flavor is defined by default). – Wiktor Stribiżew Jan 19 '23 at 12:34
  • 1
    The immediate problem is that you _cannot_ escape single quotes in single quotes; the backslash is just a literal backslash, and the single quote ends the string. The `>` is the shell telling you that (it thinks) you forgot the closing single quote. – tripleee Jan 19 '23 at 12:34
  • 1
    Just changing quotes does not solve the issue. There are several unevident immediate issues. – Wiktor Stribiżew Jan 20 '23 at 08:49

1 Answers1

1

You can use

sed "s/\(define( 'PB_PASSWORD', '\)[^']*/\1438bb1dc13ec5cbdf3b938e4fc6c3748/"

See the online demo.

Here, the POSIX BRE pattern is used:

  • \(define( 'PB_PASSWORD', '\) - Group 1 (\1 refers to this value from the RHS): the literal define( 'PB_PASSWORD', ' text
  • [^']* - any zero or more chars other than '.

Note it is fine to use a digit right after \1 as you can only define up to 9 group backreferences in a POSIX regex flavor.

In your environment, you can use

sed -i "s/\(define( 'PB_PASSWORD', '\)[^']*/\1438bb1dc13ec5cbdf3b938e4fc6c3748/" todo.txt
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563