2

I occasionally need to run a command such as:

mv "very-long-file-name.x" "very-long-file-name.y"

I would like to achieve this without repeating the very long file name twice...

I know how to do this by passing just "very-long-file-name" once to a bash script which would then use $1 ... but how can I do this without a script?

1
  • You can define as many copies as you need and use them earlier. vlf=$very-long-file-name vif2=$vif mv "$vif.x" "$vif.y"
    – seeiespi
    Oct 1, 2019 at 20:21

2 Answers 2

3

bash lets you define variables before the command, like this:

X="very-long-file-name" bash -c 'mv "${X}.x" "${X}.y"'

But beware that variables defined this way are only defined for the environment that command runs in, not in the parent shell environment. So you have to have that bash -c in there, and put single-quotes around the the subshell argument string, otherwise the variables will be interpreted in the parent shell, where they're not defined.

3
  • running exactly this in the OS X terminal I'm getting: mv: rename .x to .y: No such file or directory
    – GJ.
    Jun 1, 2014 at 7:59
  • however, this works: export X="very-long-file-name" && mv "${X}.x" "${X}.y"
    – GJ.
    Jun 1, 2014 at 8:01
  • @GJ. Oops, I'd forgotten that that syntax trick only defines the variable for the subshell. I've updated my answer to fix it.
    – Spiff
    Jun 2, 2014 at 0:40
6

Make use of Brace Expansion:

mv very-long-file-name.{x,y}

Do not quote the {x,y} part. Do not add a space before or after any brace or the comma.

After expansion, this will result in:

mv very-long-file-name.x very-long-file-name.y

Not the answer you're looking for? Browse other questions tagged .