-1

I work in an X11 window on a MAC OS X machine. Now I have hundreds of files in one directory, each file name containing a substring such as "1970", "1971",..., "2014", etc. indicating that the file is for that year. Now I have just created subdirectories named "1970", "1971", ..., "2014".

What is the one-line UNIX command that would move all the files into the subdirectories corresponding to their years?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52

1 Answers1

0

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Jonathan: Thank you very much for the answer and detailed explanation. I will save this for the future, as I need similar operations fairly often. – Roland Longbow Mar 24 '15 at 01:26