Search code examples
variablespathzshquotingbrace-expansion

zsh brace expansion for argument containing spaces supplied from a variable


In zsh, how can I use brace expansion for an argument containing spaces supplied from a variable?

e.g., I want to rename a file from ~/a b/1.txt to ~/a b/2.txt.

I can do this manually from the command line using brace expansion (but without using a variable) by backslash escaping the space and by not quoting the brace expansion path, via:

mv ~/a\ b/{1,2}.txt

None of the following work:

mv '~/a b/{1,2}.txt'

mv "~/a b/{1,2}.txt"

mv $'~/a b/{1,2}.txt'

mv '~/a\ b/{1,2}.txt'

mv "~/a\ b/{1,2}.txt"

mv $'~/a\ b/{1,2}.txt'

I want to be able to do this with the value of a variable, like:

bep='~/a\ b/{1,2}.txt'
set -x
mv "${bep}"
mv ${bep}
mv $bep
set +x

But this doesn't work.

zsh reports (because of set -x) that the command that is run is:

mv '~/a\ b/{1,2}.txt'

Neither changing the quotes for, nor removing the backslash from escaping the space in, bep='~/a\ b/{1,2}.txt' changes anything.

Neither the (Q) nor the any of the (q) parameter expansion flags seem to help.

I assume that I should be trying to prevent zsh from surrounding the argument with single quotes, but I don't know how to do that concisely.

Or maybe there's some way to enable brace expansion from within single quotes.

Or…


Solution

  • is something along the below what you are attempting to do ?

    touch a\ b/1.txt
    mv a\ b/{1,2}.txt
    mv a\ b/{2,1}.txt
    
    ll -r a\ b
    total 0
    -rw-r--r--  1 tick talkies   0 12 Jun 18:51 1.txt
    drwxr-xr-x  3 tick talkies  96 12 Jun 18:51 .. 
    drwxr-xr-x  3 tick talkies  96 12 Jun 18:53 .
    
    beb='mv a\ b/{1,2}.txt'
    
    eval $beb     
    
    ll a\ b/2.txt    
    -rw-r--r--  1 tick talkies  0 12 Jun 18:51 a b/2.txt
    

    NB: the use of eval is generally frowned upon as possible injection of dodgy commands , if however you are in full control then its less so.

    as always, test/check/double-check all code offered/shown