Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I need to move files based on a year. I used the find command

find /media/WD/backup/osool/olddata/ -mtime +470 -exec ls -lrth {} \;|sort -k6

but for this command to successfully execute i need to know the exact mtime now 470 is just a guess. Means if I can give the year 2012 it gives me files only related to 2012.

So i need advice on how to

Find files based on year e.g 2012 and move them to other directory.

OS release 5.2

FIND version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX 
share|improve this question
    
Does it make sense to use -exec ls ... \; instead of -exec ... +? Is your find too old for that? In that case find ... -print0 | xargs -0 ls... would be much faster. –  Hauke Laging Apr 22 '13 at 13:27
    
I wish these questions (and answers) that deal with coreutils would routinely specify whether we're dealing with GNU or BSD (or other) utils. –  labyrinth Jan 23 at 17:44
add comment

4 Answers 4

You want to use the -newermt option for find:

find /media/WD/backup/osool/olddata/ -newermt 20120101 -not -newermt 20130101

to get all the files with modification time in 2012.

If your find does not support -newermt you can also do the following to prevent using offset calculations:

touch -d 20120101 /var/tmp/2012.ref
touch -d 20130101 /var/tmp/2013.ref
find /media/WD/backup/osool/olddata/ -newer /var/tmp/2012.ref -not -newer /var/tmp/2013.ref
share|improve this answer
    
-newermt flag is not available in Find command –  OmiPenguin Apr 22 '13 at 12:56
    
That must be an old version of find that your RHEL comes with? I will provide an alternative in the answer for that –  Anthon Apr 22 '13 at 13:03
    
Yes this one is 5.2 –  OmiPenguin Apr 22 '13 at 13:05
    
I take it that is the revision of RHEL, not of find (I have find version 4.4.2) –  Anthon Apr 22 '13 at 13:07
    
GNU find version 4.2.27 Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX –  OmiPenguin Apr 22 '13 at 13:21
show 2 more comments

According to the man page, the argument to -mtime is the number of days you're looking for. You can use date +%j to find the number of days since January 1st of the current year.

share|improve this answer
2  
Nice way. To be very "nitpicky" : -mtime -1 : is any file in the last 24hours. Not just the files from yesterday (or today). So, there will also be a little "overlap" : if you determine it's been 120 days since 2012, and today it is 15:45 when you launch the script, you'll end up selecting files up to dec 31 15:45 (and not the last ones of that day)... You can probably use: nb_day - 1, and then "weed out" the few ones who dates from 2013 (those could be found by a ls -l | grep -v, BUT the output differ if they are 1 day old only... lots of pitfalls...) –  Olivier Dulac Apr 22 '13 at 12:53
    
You do want to use the -daystart option if you are going to work with -mtime. Otherwise you will have problems with files around the beginning and end of the year whatever way you turn unless you run this exactly at midnight. You can do the offset more accurately with -mmin than with -mtime if you can find the number of minutes since the new year easily. But the same problem exists with that as with -mtime, just for fewer files (those one minute around midnight newyear). –  Anthon Apr 22 '13 at 13:49
1  
Yeah, re-reading the man page I am seeing how it breaks it down to hours so doing a simple find -mtime $("date -+%j") probably won't give the OP what they're going for. I'm leaving it up for posterity though since this seems like a possible blindspot for people to fall into. –  Joel Davis Apr 22 '13 at 15:03
add comment
touch --date=2011-12-31T23:59:59 start
touch --date=2012-12-31T23:59:59 stop
find / -newer start \! -newer stop -printf %Tx" "%p\\n

-exec ls doesn't make any sense.

share|improve this answer
1  
-exec ls -l makes more sense, and even more while testing. –  Michael Kjörling Apr 22 '13 at 13:17
    
@MichaelKjörling find can print everything that ls can. OK, with one exception: escaping / quoting of unpleasant chars. But in general the output of find can be sorted directly. Useless calls of ls don't make the whole thing faster. –  Hauke Laging Apr 22 '13 at 13:28
    
I very often use something quite similar (although personally I prefer -print or possibly -ls) while testing. The advantage of using -exec ls {} is that it already executes something external to find. So by the time you switch from ls to mv, the actual changes are minimal. –  Michael Kjörling Apr 22 '13 at 13:31
add comment

You can try to use a combination with the stat and/or date commands as in the following one-liners:

BSD / Mac OS X:

find . -type f -print | while read file; do eval `stat -s "$file"`; year=`date -jf "%s" "+%Y" "$st_mtime"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

Linux:

find . -type f -print | while read file; do year=`date -r "$file" "+%Y"`; dest="/path/to/destination/$year; mkdir -p "$dest"; mv "$file" "$dest"; done

In both cases the approach is to use the date command to extract the year from the last modification time of every file and then to construct a path with this year. The command mkdir -p will create this path if it doesn't exist already. Of course you can use some other find options to refine your search.

share|improve this answer
add comment

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.