If the year-name sub-directories are in the single directory that currently contains all the files, then you should be able to use something like this, assuming that the current directory is that single directory:
shopt -s nullglob
for year in {1970..2014}
do
mv *?${year}* $year
mv *${year}?* $year
done
The globbing insists on at least one more character in the name to be moved than just the year, either before or after the year, to prevent an attempt to move 1970
into itself (which would fail). You need two mv
commands to prevent a-1970-b
from matching both glob expressions (which would cause the second to fail as the file would have already been removed). Using globbing like this preserves spaces etc in file names correctly. (Using command substitution, etc, does not.)
The shopt
command means that if there are no files for a given glob, there'll be nothing in the output. That will generate a usage error from mv
(a nuisance), but is otherwise harmless. You could decide to filter such error messages if you really want to; you probably don't want to send all error messages to /dev/null
, though.
Since you're on a Mac, you don't have GNU mv
with the very useful -t target
option.
You said you need a single line command; replace each newline except the one after do
with a semicolon; replace the newline after do
with a space.
If you know that the year is never at the beginning or end of the file name, you can use a single mv *?${year}?* $year
command.