user2755742
user2755742

Reputation: 43

Batch mv or rename in bash script - append date as a suffix

After much searching and trial and error, I'm unable to do a batch mv or rename on a directory of files. What I'd like to do is move or rename all files in a directory so that the mv'd or renamed file has $date (+ '%Y%d%m') added to the original suffix.

All the original files have unique prefixes but are either .xml or .txt so I'd like to go from org_prefix.org_suffix -> org_prefix.org_suffix.DATE

I've tried this:

$ mv /directory/* /directory/*$(date (+ '%Y%m%d') 

but always get /directory/*.actualdate' is not a directory error.

I've tried this:

$ for f in *; do mv $ $f.$(date +'_%m%d%y'); done 

but I get mv: cannot stat '$'; No such file or directory

Lastly, I've even tried this:

$ rename 's/*/.test/' * 

just to see if I could change all the files to org_prefix.test but nothing happens (no errors, nada, zip)

Any help greatly appreciated.

Upvotes: 4

Views: 7370

Answers (2)

gniourf_gniourf
gniourf_gniourf

Reputation: 46823

The proper way to loop through files (and e.g., print their name) in the current directory is:

for file in *; do
    echo "$file"
done

How will you append the date? like so, of course:

for file in *; do
    echo "$file.$(date +%Y%m%d)"
done

And how are you going to do the move? like so, of course:

for file in *; do
    mv -nv -- "$file" "$file.$(date +%Y%m%d)"
done

I've added:

  • -v so that mv be verbose (I like to know what's happening and it always impresses my little sister to watch all these lines flowing on the screen).
  • -n so as to no overwrite an otherwise existing file. Safety first.
  • -- just in case a file name starts with a hyphen: without --, mv would confuse with an option. Safety first.

If you just want to look through the files with extension .banana, replace the for with:

for file in *.banana; do

of for files that contain the word banana:

for file in *banana*; do

and so on.

Keep up with the bananas!

Upvotes: 5

eminor
eminor

Reputation: 933

$ mv /directory/* /directory/*$(date (+ '%Y%m%d')

This does not work, because the * is expanded to a list of all files, so after the expansion the command will be something like:

mv /directory/file1 /directory/file2 /directory/file3 /directory/file1_date /directory/file1_date ...

So you have specified many destinations, but the syntax for mv allows only one single destination.

for f in *; do mv $ $f.$(date +'_%m%d%y'); done

Here you forgot the f after the $, that's why you get the error message.

for f in *; do mv $f $f.$(date +'%m%d%y'); done

I think this should work now, but don't forget to quote all the variables!

Finally:

for f in *; do mv "$f" "$f.$(date +'%m%d%y')"; done

Edit: When there are characters directly after a variable, it's good practice to use {} to make clear that they are not part of the variable name:

for f in *; do mv "$f" "${f}.$(date +'%m%d%y')"; done

Upvotes: 1

Related Questions