I don't understand the error in my bash script.

#!/bin/bash
newFile=""
for file in *
do
    newFile={$file/ /_}     # so as to replace spaces with underscores
    mv {$file} {$newFile}
done

It complains that newFile is not a command in the line newFile={$file/ /_}

I guess I'm doing things wrong, but I keep stumbling on that point.

share|improve this question
    
why not use a simple sed -i s/ /_/g * – amisax Jun 25 '15 at 13:50
3  
You need to place the $ in front of the { like ${file} and ${file/ /_} – Lambert Jun 25 '15 at 13:50
1  
@AmitKumar; The OP wants to rename the files, not replacing all the spaces with _ within the files. – Lambert Jun 25 '15 at 13:52
3  
And besides quoting the variable use also ${file// /_} (a double slash after file) to have all the spaces replaced with an underscore instead of only the first one. – Lambert Jun 25 '15 at 13:54
up vote 2 down vote accepted

You need to move the position of the $ and add a last / to the sub to perform it for all spaces. You also need to quote the variables as it will see the space in the filename as a delimiter between the arguments for mv.

#!/bin/bash
newFile=""
for file in *
do
    newFile=${file// /_}     # so as to replace spaces with underscores
    mv "{$file}" "{$newFile}"
done

Although as stated in the other answer, half of this script is redundant.

newFile=""

Is not needed at all as the variable can be first referenced in the assignment later on.

 newFile=${file// /_}

Although the assignment itself is also not needed as the parameter substituion does not alter the original.

So it can be rewritten as

#!/bin/bash
for file in *
do
    mv "${file}" "${file// /_}" 
done
share|improve this answer
    
@don_crissti I hadn't finished editting it sorry. – 123 Jun 25 '15 at 14:03
    
@don_crissti also do you not get a 5 min grace period on this site ? – 123 Jun 25 '15 at 14:04
    
@don_crissti Dunno what its called i just heard someone say that once, on stackoverflow you have 5 mins to edit the answer without it coming up as edited. – 123 Jun 25 '15 at 14:06
    
You have maybe a couple of minutes not more... – don_crissti Jun 25 '15 at 14:50
    
@don_crissti ah right, okay :) – 123 Jun 25 '15 at 14:59

To answer your question based on the comments on your question:

  1. You need to put the dollar charachter $ before the curly brace character {.
  2. Besides that it is a good practice to quote ("") your variables.
  3. And finally, to have all the spaces replaced by an underscore you need to use two slashes (//) to be 'greedy' on the replacement.

So a sample script will look like:

#!/bin/bash

for myfile in *
do
    mv "${myfile}" "${myfile// /_}"
done

Note: There is no need to have an additional variable to hold the new name

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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