0

In Bash, I want to rename a file so that the prefix up to - is removed, but why does it not work with brace expansion?

$ ls
Thomas Anderson, Michael Dahlin-Operating Systems

$ mv {Thomas\ Anderson,\ Michael\ Dahlin-,}Operating\ Systems
mv: target ‘Operating Systems’ is not a directory
1

Your file contain , which is special to brace expansion, so your brace expansion expanded to 3 strings, instead of two as you intend.

You can try:

$ printf '%s\n' {Thomas\ Anderson,\ Michael\ Dahlin-,}Operating\ Systems
Thomas AndersonOperating Systems
 Michael Dahlin-Operating Systems
Operating Systems

to see how brace expansion was expanded.


The quick fix is escaping the ,:

$ printf '%s\n' {Thomas\ Anderson\,\ Michael\ Dahlin-,}Operating\ Systems
Thomas Anderson, Michael Dahlin-Operating Systems
Operating Systems
  • Thanks. Why in bash, when I type the beginning of the filename and let it auto-complete, , isn't escaped, while in brace expansion I have to escape it? – Tim Apr 13 '16 at 2:07
  • What characters are special in "filename generation"? Does the manual say that somewhere? – Tim Apr 13 '16 at 2:25
  • By "filename generation", do you mean "filename expansion" or "filename autocompletion"? I thought you meant the latter. Do they both have the same special characters? – Tim Apr 13 '16 at 2:48
  • @cuonglm Why not use "simple quoting": printf '%s\n' {"Thomas Anderson, Michael Dahlin-",}"Operating Systems" faster, easier to understand and less prone to making mistakes. – user79743 Apr 13 '16 at 3:05
  • @cuonglm The focus should be in giving the best way to repeat a correct use in the future. Quoting is the best solution to learn. – user79743 Apr 13 '16 at 3:12
1

Perhaps the easiest way is to use printf and set --.

Just the short version:

$ set -- {"Thomas Anderson, Michael Dahlin-",}"Operating Systems"
$ mv "$@"
$ ls
Operating Systems  

Or the more detailed description: The original is not what you want:

$ printf '%s\n' {Thomas\ Anderson,\ Michael\ Dahlin-,}Operating\ Systems
Thomas AndersonOperating Systems
 Michael Dahlin-Operating Systems
Operating Systems

When it becomes what you want (quoting is the easiest way):

$ printf '%s\n' {"Thomas Anderson, Michael Dahlin-",}"Operating Systems"
Thomas Anderson, Michael Dahlin-Operating Systems
Operating Systems

Just change the printf to set -- and use mv "$@"

$ mkdir mydir
$ cd mydir
$ touch 'Thomas Anderson, Michael Dahlin-Operating Systems'
$ ls
Thomas Anderson, Michael Dahlin-Operating Systems
$ printf '%s\n' {"Thomas Anderson, Michael Dahlin-",}"Operating Systems"
Thomas Anderson, Michael Dahlin-
Operating Systems
$ set -- {"Thomas Anderson, Michael Dahlin-",}"Operating Systems"
$ printf '%s\n' "$@"
Thomas Anderson, Michael Dahlin-
Operating Systems
$ mv "$@"
$ ls
Operating Systems

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.