Issue with Linux find command - linux

I have written a script to create an array of files that are modified more than 1 day back, iterate through the array and delete them interactively. Somehow the script is not working.
Below is the code:
#!/bin/bash
#take input from user for directory
read -p "Please enter the directory path from which you want to remove unused files" path
#create an array of files modified 2 days back
readarray -t files < <(find "$path" -maxdepth 0 -type f -mtime +1)
#remove the files iteratively and interactively
for file in "${files[#]}"; do
rm -i "$file"
done
This script isn't deleting anything. I have some files created on 12th Jan and untouched after that, but they're still there.
Can you please mention if something is missing here?

-mtime only considers full days, meaning +1 means "at least 2 days ago". From man find:
-atime n
File was last accessed less than, more than or exactly 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.
-mtime n
File's data was last modified less than, more than or exactly n*24
hours ago. See the comments for -atime to understand how rounding
affects the interpretation of file modification times.
You might also want to consider -exec of find instead of storing in an array. This will avoid all sorts of problems when your file names contain special characters, such as blanks, newlines, or globbing wildcards:
find "$path" -maxdepth 0 -type f -mtime +1440 -exec rm {} +
(a day has 1440 minutes (=60*24))

Related

Inputing directories/files into a text file and then showing files older than certain date

I'm using "ls -alR" to input directories and files in those directories into another text file.
ls -alR > testalR.txt
text file is created like so:
./test-file_folders/test_folder_1:
total 400
drwx------ 5 "user" "group" "size" May 2 10:30 test_file_1
.... file info ... more file info ....test_file_2
...more files
./test-file_folders/test_folder_2:
total 400
drwx------ 5 "user" "group" "size" Oct 2 11:35 test_file_1
.... file info ... more file info ....test_file_2
...more files
I am trying to show files that have not been accessed since October 2 2018.
I've tried:
`sed -n '/Oct 2 00:00/,/Oct/ 2 23:59/p' /testalR.txt
..but it produces no results. Is there a better way to display this or even possible?
Sorry, should have added this to begin with. I know using find -atime variant would be the best option. But we are using a system and a process that is bogged down by the find command. I am trying to find alternatives so using "find" can be avoided and wouldn't have to access directories directly each time I wanted to run a search.
Parsing the output of ls is a slippery slope.
Use find:
find . -type f -atime +3 -print
find . -type f -atime +3 -exec ls -uld {} +
Using -print simply returns a list of the filenames. Using -exec ls -ld {} + causes ls to be run for every file returned, giving you the details you may want.
The argument. to atime (or mtime or ctime) is in 24-hour steps. The argument can be positive or negative (or zero). Using -atime +3 finds a files that have been accessed at least FOUR days ago.
Using -exec ... {} + causes the command in "..." to be executed for every object returned, bundling as many objects (files) as possible at a time. This is much more efficient than forking a process for every file returned, as with:
... -exec ls -uld {} \;
One way to limit your results to a specific date, is to create two reference points (files) like this:
touch -amt 201809302359 f1
touch -amt 201810012359 f2
find . -type f \( -anewer f1 -a ! -anewer f2 \) -exec ls -uld -exec {} +
try with find:
find /folder -atime +30
where +30 = days
others params: man find

Shell script to find recently modified files [duplicate]

E.g., a MySQL server is running on my Ubuntu machine. Some data has been changed during the last 24 hours.
What (Linux) scripts can find the files that have been changed during the last 24 hours?
Please list the file names, file sizes, and modified time.
To find all files modified in the last 24 hours (last full day) in a particular specific directory and its sub-directories:
find /directory_path -mtime -1 -ls
Should be to your liking
The - before 1 is important - it means anything changed one day or less ago.
A + before 1 would instead mean anything changed at least one day ago, while having nothing before the 1 would have meant it was changed exacted one day ago, no more, no less.
Another, more humanist way, is to use -newermt option which understands human-readable time units.
Unlike -mtime option which requires the user to read find documentation to figure our what time units -mtime expects and then having the user to convert its time units into those, which is error-prone and plain user-unfriendly. -mtime was barely acceptable in 1980s, but in the 21st century -mtime has the convenience and safety of stone age tools.
Example uses of -newermt option with the same duration expressed in different human-friendly units:
find /<directory> -newermt "-24 hours" -ls
find /<directory> -newermt "1 day ago" -ls
find /<directory> -newermt "yesterday" -ls
You can do that with
find . -mtime 0
From man find:
[The] time since each file was last modified is divided by 24 hours and any remainder is discarded. That means that to
match -mtime 0, a file will have to have a modification in the past which is less than 24 hours ago.
On GNU-compatible systems (i.e. Linux):
find . -mtime 0 -printf '%T+\t%s\t%p\n' 2>/dev/null | sort -r | more
This will list files and directories that have been modified in the last 24 hours (-mtime 0). It will list them with the last modified time in a format that is both sortable and human-readable (%T+), followed by the file size (%s), followed by the full filename (%p), each separated by tabs (\t).
2>/dev/null throws away any stderr output, so that error messages don't muddy the waters; sort -r sorts the results by most recently modified first; and | more lists one page of results at a time.
For others who land here in the future (including myself), add a -name option to find specific file types, for instance: find /var -name "*.php" -mtime -1 -ls
This command worked for me
find . -mtime -1 -print
Find the files...
You can set type f = file
find /directory_path -type f -mtime -1 -exec ls -lh {} \;
👍

Move files that are 30 minutes old

I work on a server system that does not allow me to store files more than 50 gigabytes. My application takes 20 minutes to generate a file. Is there any way whereby I can move all the files that are more than 30 minutes old from source to destination? I tried rsync:
rsync -avP source/folder/ user#destiantionIp:dest/folder
but this does not remove the files from my server and hence the storage limit fails.
Secondly, if I use the mv command, the files that are still getting generated also move to the destination folder and the program fails.
You can use find along with -exec for this:-
Replace /sourcedirectory and /destination/directory/ with the source and target paths as you need.
find /sourcedirectory -maxdepth 1 -mmin -30 -type f -exec mv "{}" /destination/directory/ \;
What basically the command does is, it tries to find files in the current folder -maxdepth 1 that were last modified 30 mins ago -mmin -30 and move them to the target directory specified. If you want to use the time the file was last accessed use -amin -30.
Or if you want to find files modified within a range you can use something like -mmin 30 -mmin -35 which will get you the files modified more than 30 but less than 35 minutes ago.
References from the man page:-
-amin n
File was last accessed n minutes ago.
-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.
-mmin n
File's data was last modified n minutes ago.
-mtime n
File's data was last modified n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretation of file modification times.

Find file according to the access time using "grep" and "find" commands

My goal is to find all text files with extension .log, which have the last access more than 24 hours ago and contain the required text.
Here is what I have already tried:
find / *.log -mtime +1 -print | grep "next" *.log
but this doesn't work.
Question is: how can I reach the goal I have described above?Maybe some ways to modify my find expression?
The problem with your command is that you are running the grep on the output of the find command - which means you are running it on the file names, not content (actually, since you have the *.log at the end, you run it on all *.log files, completely ignoring what your find command found). also, you need -name in order to filter only the .log files.
you can use the -exec flag of find to execute a command on each of the files that matches your find criteria:
find / -name "*.log" -mtime +1 -exec grep 'next' \{};
Try with xargs:
find / -name "*.log" -mtime +1 | xargs grep "next"
But also, note what the find manual says about the arg to -atime which also applies to -mtime. That is, your mtime as specified probably doesn't get the time period you want.
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.

linux script that will delete files from previous month

I am new in linux scripting and I have never created .sh file before.
I need to create a script that will delete all the files which are from previous month.
I have gone through the
find /path/to/files* -mtime +5 -exec rm {} \;
but find useless as days in a month can vary from 30 -31 days.
Please help me on this problem. thanks
Run below commands to delete last month file in working Directory.
1st you can see last moth files in working directory run
sudo find . -mtime +30
Numeric arguments can be specified as
+n for greater than n,
-n for less than n,
n for exactly n.
sudo find . -mtime +30 -delete
to delete all files in the systems you can run as below
sudo find / -mtime +30 -delete
Well, first off - how important is it your purge last month? I mean - if you run your script on May 1st, are you really expecting to delete the files from last night?
For most purposes - find -mtime +30 is sufficient, as it's a rolling 30d window.
However, if you really want to 'last month and older' then you have to get a bit more creative, because Unix works on time stamps - in seconds. 30d in seconds is a fixed window, but as you note - 1 calendar month is not.
It gets worse yet if you bear in mind that 'last month' may well also be 'last year' as well.
So to get exactly one month ago:
perl -MTime::Piece -e 'print localtime -> add_months(-1);'
To turn that into a Unix timestamp:
perl -MTime::Piece -e 'print localtime -> add_months(-1) -> epoch;'
To actually figure out the time stamp of the start of the last month is slightly more complicated though - the easiest way is probably to do the above, and then 'figure out' the time stamp of the first day.
E.g.
perl -MTime::Piece -e 'print localtime->strptime(localtime->add_months(-1)->strftime("%Y%m"),"%Y%m);'
We subtract 1 month from today, reformat it as 'year/month' and then re-parse 'year/month' with no day to get the first day of the month.
Obligatory bash solution. From the working directory containing the files to remove, you could run this
for i in $(ls -al | awk '/May/{print $NF}'); do rm -rf $i; done
It will explicitly match all files create in May and then remove them.
The ls -al command lists out the files with their dates and then the awk command matches the files with a date of May and then prints out only the file name. You can test it out before pulling the trigger by running this
ls -al | awk '/May/{print $NF}'
Once you are certain that the files being found are the ones you want to remove, you can run the for loop to remove them.

Resources