0

I am trying to use wp cli (with regex) to search and replace.

I want to change:

domain.com/wp-content/uploads/2020/04/asdnbahsdjhgzw/picture.jpg

to

domain.com/wp-content/uploads/2020/04/picture.jpg

So I want to get rid of the "asdnbahsdjhgzw" part.

Now I tried something like:

wp search-replace "domain.com/wp-content/uploads/(\d)/(\d)/(\d*)/" "domain.com/wp-content/uploads/\$1/\$2/" --precise --all-tables --skip-columns=guid --regex
  • (\d)/(\d)/ to match and "capture" the directory structure for media and thought I would be able to call them back in the replacement with /$1/$2/.
  • (\d*)/ is to capture the random directory name, asdnbahsdjhgzw/, and don't call it back in the replacement.

BUT

Unfortunately, this isn´t working as I had hoped. I get the following error:

syntax error near unexpected token `('

I also tried the backslash before the (

/\(\d\)/\(\d\)/\(\d*\)/

But no luck.

Perhaps someone knows what could be the issue, apart from me not knowing WP CLI ;)

thanks!

1
  • When I try your command, it works without any problems. Using WP CLI 2.5.0 in Alpine with Bash.
    – kero
    Nov 8 at 14:35
2

Instead of using " to wrap your expressions, use '.

Further experimenting shows me that this is incorrect—both " and ' should work, as long as they're matched (ie, you don't accidentally try something like wp search-replace "domain.com/wp-content/uploads/(\d)/(\d)/(\d*)/' "domain.com/wp-content/uploads/\$1/\$2/" --precise --all-tables --skip-columns=guid --regex. (Note that the regex in that example starts with " and ends with '.)

I'm not deleting this answer because the info below, about the regex itself, still stands.

The regex

Your regex looks wrong to me. \d will match a single digit, so it'd match, eg, 1, 5, etc, but not 2020 or 04.

I'd recommend something like this:

wp search-replace
--dry-run
'domain.com/wp-content/uploads/(\d+)/(\d+)/[^/]+/'
'domain.com/wp-content/uploads/\$1/\$2/'
--precise --all-tables --skip-columns=guid --regex

(line breaks added for readability; all this should be on a single line)

The [^/]+ will match everything but a / character in that last segment of the regex search. I also took out the () wrapping it since you're discarding it.

I also strongly recommend using the --dry-run argument with wp search-replace first, to see what you'll be replacing.

Edited again to add: I've removed the text about my deeper dive into using ' vs. " in bash, because it seems it was incorrect.

5
  • 1
    Can you (briefly) explain, why ' will work and " not?
    – kero
    Nov 8 at 15:32
  • @kero - I tried, but somehow I think I may have confused myself more on how bash works.
    – Pat J
    Nov 8 at 16:30
  • 1
    Thanks for the explanation. Could you reproduce OP's problem? For me (in docker container running Alpine, Bash "GNU bash, version 5.1.4(1)-release (x86_64-alpine-linux-musl)") it worked with " ...
    – kero
    Nov 8 at 17:36
  • That's weird. When I tried it before, I thought it gave me the bash error OP was getting; but now when I try it, it works fine. It only gives me the error if I have an unmatched " (which makes sense to me). I've updated my answer to reflect this.
    – Pat J
    Nov 8 at 19:09
  • @kero Paging up through my shell's history, I see that I made it fail by not using quotes at all (which of course throws the error).
    – Pat J
    Nov 8 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.