2

I am trying to use variable in renaming a file. However, I when insert the variable to the beginning of the filename, things does not work as expected.

Here's the case, I have a file name test:

$ ls
test

and a variable i=1

When adding the variable to the end or middle of filename, it works:

$ mv test test_$i
$ ls
test_1

When adding the variable to the beginning of filename, it doesn't work:

$mv test_1 test  
$mv test $i_test
mv: missing destination file operand after 'test'
Try 'mv --help' for more information.

And even worse, when there is extension in my filename, the file will be removed.

$ touch test.try
$ ls
test.try
$ mv test.try $i_test.try
$ ls
 (nothing!)

Can anyone explain this to me? Is it a bug or something I don't know?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
once
  • 1,369
  • 4
  • 22
  • 32

1 Answers1

3

You need to put {} around the variable name to disambiguate it from the rest of the literal (remember, _ is a valid character in an identifier):

mv test.try ${i}_test.try

or, use double quotes, which gives you protection against word splitting and globbing:

mv test.try "${i}"_test.try

In your code:

$i_test     => shell treats "i_test" as the variable name
$i_test.try => shell treats "i_test" as the variable name ('.' is not a valid character in an identifier)

mv test.try $i_test.try => test.try got moved to .try as "$i_test" expanded to nothing.  That is why ls didn't find that file.  Use 'ls -a' to see it.

See this related post: When do we need curly braces in variables using Bash?

Community
  • 1
  • 1
codeforester
  • 39,467
  • 16
  • 112
  • 140