Delete files older than X minutes - linux

I would like to delete files that are older than 59 minutes. I have this so far:
find /tmp -daystart -maxdepth 1 -mmin +59 -type f -name "*.*" -exec rm -f {} \;
This doesn't work and seems to delete all files. I've tested this several times and I think the issue is to do with daystart.
I've read the man page and it seems to base time on the beginning of the day rather than from 24 hours ago. If this is the case how can I accurately delete files that are older than 59 minutes? Do I need to account for daystart and add some more minutes?
Example:
ubuntu#ip-10-138-30-118:/tmp$ ls -la
total 8
drwxrwxrwt 2 root root 4096 Jul 20 14:39 ./
drwxr-xr-x 23 root root 4096 Jun 25 18:34 ../
-rw-rw-r-- 1 ubuntu ubuntu 0 Jul 20 12:35 a.txt
Both the following commands, return the file:
ubuntu#ip-10-138-30-118:/tmp$ find /tmp -daystart -maxdepth 1 -mmin +59 -type f -name "*.*"
/tmp/a.txt
And:
ubuntu#ip-10-138-30-118:/tmp$ find /tmp -daystart -maxdepth 1 -mmin +359 -type f -name "*.*"
/tmp/a.txt
However, the file is not older than 659 minutes (10.9 hours)! But at 759 (12.65 hours), it doesn't return the file anymore?

When used with -mmin, -daystart appears to make it calculate from the end of today, not the beginning.
If you just want to find files modified more than 59 minutes ago, you don't need that option. -mmin calculates from the current time by default.
barmar#dev:~/testdir$ date
Sat Jul 20 10:02:20 CDT 2013
barmar#dev:~/testdir$ ls -l
total 0
-rw-r--r-- 1 barmar adm 0 Jul 20 09:57 a.txt
barmar#dev:~/testdir$ find . -maxdepth 1 -mmin +2 -type f
./a.txt
barmar#dev:~/testdir$ find . -maxdepth 1 -mmin +10 -type f

this should work for you
find /path -mmin +59 -type f -exec rm -fv {} \;

Related

Deleting multiple files in Linux?

How can I delete multiple files in Linux created at same date and time? How can I manage this without using date? The file have different names.
I have these .txt files:
-rw-r--r-- 1 root root 54 Jan 6 17:28 file1.txt
-rw-r--r-- 1 root root 33 Jan 6 17:28 file2.txt
-rw-r--r-- 1 root root 24 Jan 6 18:05 file3.txt
-rw-r--r-- 1 root root 0 Jan 6 17:28 file4.txt
-rw-r--r-- 1 root root 0 Jan 6 17:28 file5.txt
How can I delete all the files with one command?
You can use find command and specify the time range. In your example: if you would like to find all files with modified timestamp from 6. Jan 17:28 you can do something like:
find . -type f -newermt '2016-01-06 17:28' ! -newermt '2016-01-06 17:29'
if you would like to delete them, just use finds exec parameter:
find . -type f -newermt '2016-01-06 17:28' ! -newermt '2016-01-06 17:29' -exec rm {} \;
you can also include -name '*.txt' if you want to process only *.txt files, and check maxdepth parameter as well if you would like to avoid processing subdirectories
simply use rm -f file*.txt to delete all files which starts with file and ends with the extention .txt
If you know the minutes of the file modified then you can deleted all files using find command. consider the file was last modified ten minutes ago. Then you can use,
find -iname "*.txt" -mmin 10 -ok rm {} \;
If you don't need to prompt before deleting then use -exec.
find -iname "*.txt" -mmin 10 -exec rm {} \;
If you need to delete the files using access time then you can use -amin

How to find files modified in last x minutes (find -mmin does not work as expected)

I'm trying to find files modified in last x minutes, for example in the last hour. Many forums and tutorials on the net suggest to use the find command with the -mmin option, like this:
find . -mmin -60 |xargs ls -l
However, this command did not work for me as expected. As you can see from the following listing, it also shows files modified earlier than 1 hour ago:
-rw------- 1 user user 9065 Oct 28 23:13 1446070435.V902I67a5567M283852.harvester
-rw------- 1 user user 1331 Oct 29 01:10 1446077402.V902I67a5b34M538793.harvester
-rw------- 1 user user 1615 Oct 29 01:36 1446078983.V902I67a5b35M267251.harvester
-rw------- 1 user user 72365 Oct 29 02:27 1446082022.V902I67a5b36M873811.harvester
-rw------- 1 user user 69102 Oct 29 02:27 1446082024.V902I67a5b37M142247.harvester
-rw------- 1 user user 2611 Oct 29 02:34 1446082482.V902I67a5b38M258101.harvester
-rw------- 1 user user 2612 Oct 29 02:34 1446082485.V902I67a5b39M607107.harvester
-rw------- 1 user user 2600 Oct 29 02:34 1446082488.V902I67a5b3aM465574.harvester
-rw------- 1 user user 10779 Oct 29 03:27 1446085622.V902I67a5b3bM110329.harvester
-rw------- 1 user user 5836 Oct 29 03:27 1446085623.V902I67a5b3cM254104.harvester
-rw------- 1 user user 8970 Oct 29 04:27 1446089232.V902I67a5b3dM936339.harvester
-rw------- 1 user user 165393 Oct 29 06:10 1446095400.V902I67a5b3eM290158.harvester
-rw------- 1 user user 105054 Oct 29 06:10 1446095430.V902I67a5b3fM265065.harvester
-rw------- 1 user user 1615 Oct 29 06:24 1446096244.V902I67a5b40M55701.harvester
-rw------- 1 user user 1620 Oct 29 06:24 1446096292.V902I67a5b41M337769.harvester
-rw------- 1 user user 10436 Oct 29 06:36 1446096973.V902I67a5b42M707215.harvester
-rw------- 1 user user 7150 Oct 29 06:36 1446097019.V902I67a5b43M415731.harvester
-rw------- 1 user user 4357 Oct 29 06:39 1446097194.V902I67a5b56M446687.harvester
-rw------- 1 user user 4283 Oct 29 06:39 1446097195.V902I67a5b57M957052.harvester
-rw------- 1 user user 4393 Oct 29 06:39 1446097197.V902I67a5b58M774506.harvester
-rw------- 1 user user 4264 Oct 29 06:39 1446097198.V902I67a5b59M532213.harvester
-rw------- 1 user user 4272 Oct 29 06:40 1446097201.V902I67a5b5aM534679.harvester
-rw------- 1 user user 4274 Oct 29 06:40 1446097228.V902I67a5b5dM363553.harvester
-rw------- 1 user user 20905 Oct 29 06:44 1446097455.V902I67a5b5eM918314.harvester
Actually, it just listed all files in the current directory. We can take one of these files as an example and check if its modification time is really as displayed by the ls command:
stat 1446070435.V902I67a5567M283852.harvester
File: ‘1446070435.V902I67a5567M283852.harvester’
Size: 9065 Blocks: 24 IO Block: 4096 regular file
Device: 902h/2306d Inode: 108680551 Links: 1
Access: (0600/-rw-------) Uid: ( 1001/ user) Gid: ( 1027/ user)
Access: 2015-10-28 23:13:55.281515368 +0100
Modify: 2015-10-28 23:13:55.281515368 +0100
Change: 2015-10-28 23:13:55.313515539 +0100
As we can see, this file was definitely last modified earlier than 1 hour ago! I also tried find -mmin 60 or find -mmin +60, but it did not work either.
Why is this happening and how to use the find command correctly?
I can reproduce your problem if there are no files in the directory that were modified in the last hour. In that case, find . -mmin -60 returns nothing. The command find . -mmin -60 |xargs ls -l, however, returns every file in the directory which is consistent with what happens when ls -l is run without an argument.
To make sure that ls -l is only run when a file is found, try:
find . -mmin -60 -type f -exec ls -l {} +
The problem is that
find . -mmin -60
outputs:
.
./file1
./file2
Note the line with one dot?
That makes ls list the whole directory exactly the same as when ls -l . is executed.
One solution is to list only files (not directories):
find . -mmin -60 -type f | xargs ls -l
But it is better to use directly the option -exec of find:
find . -mmin -60 -type f -exec ls -l {} \;
Or just:
find . -mmin -60 -type f -ls
Which, by the way is safe even including directories:
find . -mmin -60 -ls
To search for files in /target_directory and all its sub-directories, that have been modified in the last 60 minutes:
$ find /target_directory -type f -mmin -60
To find the most recently modified files, sorted in the reverse order of update time (i.e., the most recently updated files first):
$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r
Manual of find:
Numeric arguments can be specified as
+n for greater than n,
-n for less than n,
n for exactly n.
-amin n
File was last accessed n minutes ago.
-anewer file
File was last accessed more recently than file was modified. If file is a symbolic link and the -H option or the -L option is in effect, the access time of the file it points to is always
used.
-atime n
File was last accessed n*24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, any fractional part is ignored, so to match -atime +1, a file has to
have been accessed at least two days ago.
-cmin n
File's status was last changed n minutes ago.
-cnewer file
File's status was last changed more recently than file was modified. If file is a symbolic link and the -H option or the -L option is in effect, the status-change time of the file it points
to is always used.
-ctime n
File's status was last changed n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretation of file status change times.
Example:
find /dir -cmin -60 # creation time
find /dir -mmin -60 # modification time
find /dir -amin -60 # access time
I am working through the same need and I believe your timeframe is incorrect.
Try these:
15min change: find . -mtime -.01
1hr change: find . -mtime -.04
12 hr change: find . -mtime -.5
You should be using 24 hours as your base. The number after -mtime should be relative to 24 hours. Thus -.5 is the equivalent of 12 hours, because 12 hours is half of 24 hours.
Actually, there's more than one issue here. The main one is that xargs by default executes the command you specified, even when no arguments have been passed. To change that you might use a GNU extension to xargs:
--no-run-if-empty
-r
If the standard input does not contain any nonblanks, do not run the command. Normally, the command is run once even if there is no input. This option is a GNU extension.
Simple example:
find . -mmin -60 | xargs -r ls -l
But this might match to all subdirectories, including . (the current directory), and ls will list each of them individually. So the output will be a mess. Solution: pass -d to ls, which prohibits listing the directory contents:
find . -mmin -60 | xargs -r ls -ld
Now you don't like . (the current directory) in your list? Solution: exclude the first directory level (0) from find output:
find . -mindepth 1 -mmin -60 | xargs -r ls -ld
Now you'd need only the files in your list? Solution: exclude the directories:
find . -type f -mmin -60 | xargs -r ls -l
Now you have some files with names containing white space, quote marks, or backslashes? Solution: use null-terminated output (find) and input (xargs) (these are also GNU extensions, afaik):
find . -type f -mmin -60 -print0 | xargs -r0 ls -l
This may work for you. I used it for cleaning folders during deployments for deleting old deployment files.
clean_anyfolder() {
local temp2="$1/**"; //PATH
temp3=( $(ls -d $temp2 -t | grep "`date | awk '{print $2" "$3}'`") )
j=0;
while [ $j -lt ${#temp3[#]} ]
do
echo "to be removed ${temp3[$j]}"
delete_file_or_folder ${temp3[$j]} 0 //DELETE HERE
fi
j=`expr $j + 1`
done
}
this command may be help you sir
find -type f -mtime -60

crontab is not deleting the files in linux

I am trying to delete all the pdf files which are more than 30 days old at 11:30 PM
I added the below given code in crontab
30 23 * * * find /var/www/html/site/reports/ -name "*.pdf" -type f -mtime +30 | xargs -I {} rm -f {} \;
But it doesn't delete the files.
Can you please check what the issue is?
The crontab details
-rw-r--r--. 1 root root 532 Sep 30 11:14 crontab
One of the files which i need to delete
-rw-r--r-- 1 apache apache 15215 Jul 25 11:24 sales_report.pdf
You missed user and PATH. This may help
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
30 23 * * * root find /var/www/html/site/reports/ \( -name "*.pdf" \) -type f -mtime +30 -exec rm {} \; >> /tmp/debug_cron 2>&1
And then check /tmp/debug_cron
I have this working a a linux box.
30 23 * * * find /var/www/html/site/reports/ \( -name "*.pdf" \) -type f -mtime +30 -exec rm {} \;

Grep inside all files created within date range

I am on the Ubuntu OS. I want to grep a word (say XYZ) inside all log files which are created within date range 28-may-2012 to 30-may-2012.
How do I do that?
This is a little different from Banthar's solution, but it will work with versions of find that don't support -newermt and it shows how to use the xargs command, which is a very useful tool.
You can use the find command to locate files "of a certain age". This will find all files modified between 5 and 10 days ago:
find /directory -type f -mtime -10 -mtime +5
To then search those files for a string:
find /directory -type f -mtime -10 -mtime +5 -print0 |
xargs -0 grep -l expression
You can also use the -exec switch, but I find xargs more readable (and it will often perform better, too, but possibly not in this case).
(Note that the -0 flag is there to let this command operate on files with embedded spaces, such as this is my filename.)
Update for question in comments
When you provide multiple expressions to find, they are ANDed together. E.g., if you ask for:
find . -name foo -size +10k
...find will only return files that are both (a) named foo and (b) larger than 10 kbytes. Similarly, if you specify:
find . -mtime -10 -mtime +5
...find will only return files that are (a) newer than 10 days ago and (b) older than 5 days ago.
For example, on my system it is currently:
$ date
Fri Aug 19 12:55:21 EDT 2016
I have the following files:
$ ls -l
total 0
-rw-rw-r--. 1 lars lars 0 Aug 15 00:00 file1
-rw-rw-r--. 1 lars lars 0 Aug 10 00:00 file2
-rw-rw-r--. 1 lars lars 0 Aug 5 00:00 file3
If I ask for "files modified more than 5 days ago (-mtime +5) I get:
$ find . -mtime +5
./file3
./file2
But if I ask for "files modified more than 5 days ago but less than 10 days ago" (-mtime +5 -mtime -10), I get:
$ find . -mtime +5 -mtime -10
./file2
Combine grep with find:
find -newermt "28 May 2012" -not -newermt "30 May 2012" -exec grep XYZ \{\} \;
find doesn't seem to have options where you can specify specific dates for timestamp comparison (at least the version on my laptop doesn't - there may be other versions and/or other tools that perform similarly), so you'll have to use the number of days. So, as of 2012/06/05, you want to find files newer than 9 days but older than 6 days:
find . -type f -ctime -9 -ctime +6 -print0 | xargs -0 grep XYZ

How can I list files modified within a directory yesterday via command line?

I'd like to list out all files with modification dates in the last n days (or even simply after Y-m-d) in a directory. It must work recursively through all subdirectories as well.
How can I do this?
Ideal output:
file.txt Mar 26 15:15
file2.txt Mar 27 01:15
Acceptable output:
file.txt
file2.txt
Answered! (Thanks for all the help)
$ find . -type f -mtime -1 -exec ls -lah {} \;
-rw-r--rw- 1 apache apache 18K Mar 26 08:22 ./file1.txt
-rw-r--rw- 1 apache apache 12K Mar 26 09:23 ./dir1/file2.txt
-rw-r--rw- 1 apache apache 16K Mar 26 10:24 ./dir1/dir2/file3.txt
find . -type f -mtime -1 -exec ls -l {} \;
will list all files within last 24 hours, with a long listing just to confirm modification date
use :
find . -mtime +1
For more informations, see
man find
find dir -mtime +1 -print
That will find all files in dir and subdirectories that were modified 1 day ago or before that.

Resources