Get via App Store Read this post in our app!
How to find files inbetween two dates using ",find",?
I have an email account that has passed 60GB of emails, and presently I’m having a lot of trouble using an email client to archive emails of last year (2011).
Via terminal, I am attempting to use find to locate the files inbetween 2011-01-01 and 2011-12-31, but no avail.
How can I find files inbetween two dates?
If relevant, the end objective will be a batch that will budge each file found, matching the date interval, to a folder.
You can use this script:
Bash find files inbetween two dates:
Comes back a list of files that have timestamps after 2010-10-07 and before 2014-10-08
Bash find files from 15 minutes ago until now:
Comes back a list of files that have timestamps after 15 minutes ago but before now.
Bash find files inbetween two timestamps:
Comebacks files with timestamps inbetween 2014-10-08 Ten:17:00 and 2014-10-08 Ten:53:00
Moving the files, and prompting the user when there are duplicate names:
As Subv3rsion’s and Eric Leschinski’s answers showcase, the -newermt predicate selects files modified more recently than the date (and optional time) specified as its operand. To find files
- anywhere in srcdir (i.e., including its subdirectories, their subdirectories, etc.)
- last modified in (for example) September 2014
- and stir them to destdir
In an -exec expression, find passes the filename found in place of <> . , indicates to -exec that the guideline to be run, and its arguments, have all been provided (in case subsequent expressions are passed to find after that particular -exec predicate’s arguments–see below for an example of this). , must be escaped as \, so it’s not interpreted specially by the shell. (Without \ , , would end the entire find guideline, working the same as a newline. Even however this find guideline has nothing after this -exec expression, failing to pass the , argument is still a syntax error.)
If you just want to list the files–which is advisable if you’re not sure how the old emails are stored or what other files may be present–omit -exec and everything to the right of it. (For email, often emails from different dates are stored in the same file, for someone in the situation described in the question here, I recommend investigating how they are stored before moving any files.) If you want to both print their names and stir them, add -print before -exec .
mv -i prompts anytime a file would be overwritten at the destination, such as would happen if:
- a file of the same name exists from a previous backup, or
- a file of the same name but from a different subdirectory of srcdir has already been moved during the same find operation, or
- (least likely) a file of the same name was created somewhere in srcdir during the same find operation, after the original was moved but soon enough to be found once find traverses a different subdirectory.
Other ways to invoke rm :
You have other options for how to treat files with duplicate names.
- Without -i (i.e., mv <>destdir/ ), mv would not usually prompt for approval, but would do so if the destination file were read-only. ( mv can even succeed at overwriting a read-only file sometimes, such as if the user running it possesses the file.)
- If you don’t want even that degree of interactivity, and want mv always to (attempt to) overwrite identically named files, use mv -f .
- If, in contrast, you want to skip source files when there is already a destination file of the same name, use mv -n .
- mv accepts the -b and –backup flags to automatically rename identically named files that already exist at the destination. By default
is added to produce the backup name, and if a file with the name and a file with the backup name already exist at the destination, the backup file is overwritten. This default can be overridden by options passed when invoking mv , and by environment variables. See man mv for details, and the example below.
Moving the files and creating backups in case of duplicate names:
To budge all files, back up files with duplicate names using a
suffix, and use numbered .
files already exist (so as to avoid overwriting anything), run:
If you skipped files with duplicate names and want to know which ones:
If you use mv -n and want to know which files were not moved because there was another file with the same name, the best way is most likely just to run the original find instruction again, without -exec and everything to the right of it. This will print their names.
It will also print the names of any matching files created since you ran the original find . -exec . instruction, but for this application there will typically be none since you’re looking for files with old modification times. It’s possible to give a file a modification timestamp older than its real age, with touch and other mechanisms, but that doesn’t seem likely to occur in this case without your skill.
Knowing instantly as files are skipped due to duplicate names:
mv -n doesn’t report, nor come back any special exit code, when it refrains from moving a file. So if you want to be instantaneously informed of skipped files while find runs, you’ll have to make a separate step for that. One way is:
A few most likely minor technical considerations: This warns incorrectly if mv fails to copy a file for a different reason than it existing at the destination and exits reporting success. That seems unlikely, but I’m not certain it’s unlikely. It also potentially suffers a race condition: it would warn when there is no real error at all, if a fresh file of the same name were created in the same place during the very brief time after the old file was moved and before the check to see if it was eliminated. (Considering the application, I doubt either problem would ever actually occur.) It could be rewritten to check the destination before moving the file instead of after: then the race condition would relate to freshly created destination files instead of source files. And while errors and warnings reported by find or mv (or [ , however there shouldn’t be any) will be written to standard error, our . skipped (exists in. warning gets written to standard output. Normally both show up on your terminal, but this may matter if you’re scripting.
I’ve split that guideline onto two lines for lighter reading. It can be run that way, or you can liquidate the \ and the newline (i.e., the line break).
How does that find instruction work?
find predicates can be tests (like -type and -newermt ), used for their come back values, or deeds (like -print and -exec ), which are often used for their side effects.
When no operator (like -a for and, -o for or) is supplied inbetween expressions, -a is implied. find employs short-circuit evaluation for and and or. p q (i.e., p -a q ) is true only if the p and q expressions are both true, so q needn’t be evaluated if p is false. However we often don’t think of it in these terms, this is why tests have to be true for subsequent deeds or tests to be evaluated. For example, suppose find comes upon a directory. It evaluates -type f to false, so it can skip everything afterwards.
Like tests, deeds evaluate to true or false as well. In this way, -exec reports if the executed directive exited reporting success (true) or failure (false). We have this chain of -exec expressions connected with implicit and:
This attempts to budge the file, and if mv reports failure, stops. We don’t want to warn about a correctly skipped file if some other problem was why it wasn’t moved.
But if it succeeded, it then runs the [ guideline. Like find , [ supports its own kind of expressions passed as arguments. [ -f <> ] checks if the operand after -f (passed to it by find in place of <> ) exists (and is a regular file), and comebacks either true/success or false/failure.
(Many guidelines’ exit statuses are best interpreted as signifying success or failure, but [ ‘s exist status is usually best interpreted as true or false.)
If [ returned false, then the file is gone, so it was moved, so there’s no need to do anything. But if [ returned false, the file is still there. Then find evaluates the next -exec expression, which prints the warning message.