How can I move or delete files created in certain time range?
Solution 1:
With stat
(assumes all files in the same directory)
stat -c '%y %n' * | grep -E ' (22:4[5-9]|22:5|23:|0[0-4]:)' | cut -d ' ' -f 4 | xargs mv -t $dirForRemovedFiles
- this assumes that in the output of stat isn't depend on locale (it doesn't seem to be...), otherwise force the locale to "C".
- this assume that all the files are in the same DST segment.
- note the space between the quote and the parenthesis, this is what makes the regexp match only the beginning of the time stamp.
- for safety, the command above doesn't delete anything, it just moves the files to a directory where you'll issue a
rm *
once you have asserted that you aren't missing anything. - if you are paranoid, use
grep -E '^.{10} (22:4[5-9]|22:5|23:|0[0-4]:)'
to avoid false hits.
Solution 2:
This semi-single line will print the "nightly" files:
( \
llimit=$((60*5+0)); \
ulimit=$((60*22+45)); \
find -type f -exec bash -c '\
hm=`stat -c "%y" "$0" | cut -c 12-16`; \
t=$((60*10#`echo $hm | cut -c 1-2`+10#`echo $hm | cut -c 4-5`)); \
test \( $t -lt $1 \) -o \( $t -gt $2 \)' \
{} $llimit $ulimit \; \
-print \
)
Sub-lines explained:
- Starts a subshell to make variables local.
- Calculates the lower limit in minutes past midnight.
- Calculates the upper limit.
- For every file a separate
bash
is executed; it will do the arithmetic. - Extracts mtime as
HH:MM
. - Converts
HH:MM
to a value as minutes past midnight. - Compares this value with precalculated limits.
- These are arguments to the inner
bash
; inside, they are referred to as$0
,$1
,$2
. - Prints the path iff the previous test returns true.
- Ends the subshell.
Some remarks:
-
-exec
can act as a test infind
invocation. This is hardly obvious, yet very powerful. In this case the test is true when the final part of the innerbash
command line (i.e.test
) returns true (i.e. its exit status is0
). - Bash arithmetic (
$((…))
) parses01
or so as an octal number,08
and09
are invalid octal numbers. That's why we need to use10#
to ensure that all numbers extracted fromstat
output are interpreted as decimal. - I used
-lt
and-gt
intest
. Use-le
and/or-ge
if they suit you better. - To remove files replace
-print
with-delete
(or use them together:-print -delete
). -
To move files to a single directory replace
-print
with-print0
and build a pipe like this:( … find … -print0 ) | xargs -0r mv -t /target/directory/