Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a huge folder of around 50G in size and have different subdirectories. I want to create a script that can find the files older than different dates for some of the subdirectories and delete the files.
I assume to exclude the subdirectory-1 and subdirectory-2 from the following command and delete all files older then 15 days for all other subdirectories.
Maybe you could explain what's 'not working' in detail.
ie what errors are occurring.
In any case this path ' /../' etc doesn't make sense . You can't go 'up' from the root dir ('/').
Maybe you could explain what's 'not working' in detail.
ie what errors are occurring.
In any case this path ' /../' etc doesn't make sense . You can't go 'up' from the root dir ('/').
----------
well Simple is that I need a command/script that can delete files older than 15 days but leaving few sub-directories. I mean if i want to delete all files in all sub-direcotires of a current directory excluding two three subdirectories.
/../ that means the path to the main directory.
like /opt/shared-directory is the main directory that contains 50 subdirectories of individual students. Now i want to delete all files older than 15 days in all student directories except first three position holders.(i.e. want to exclude them)
To delete all the files from a specific directory ( and subdirectories) i can use this command
This will eliminate the directory (and it's contents)~/download/helix/ from the results, including the directory. Using -prune will still result in the directory being printed if you don't have a -type f.
Here I am grouping the two path tests and using -type f.
Code:
find ~/downloads/ -type f -mtime +15 \( -not -path '*/downloads/helix/*' -a -not -path "*/geda/*" \) -execdir ls -l '{}' \;
Would you mind explaining "/../" for me. Where would it have an advantage over simply "/"?
It starts at the root directory (the first '/') goes up one directory level (which seems odd since you are starting at root) and then selects the root directory again.
This will eliminate the directory (and it's contents)~/download/helix/ from the results, including the directory. Using -prune will still result in the directory being printed if you don't have a -type f.
Here I am grouping the two path tests and using -type f.
Code:
find ~/downloads/ -type f -mtime +15 \( -not -path '*/downloads/helix/*' -a -not -path "*/geda/*" \) -execdir ls -l '{}' \;
Would you mind explaining "/../" for me. Where would it have an advantage over simply "/"?
It starts at the root directory (the first '/') goes up one directory level (which seems odd since you are starting at root) and then selects the root directory again.
------------
Thanks to all of you who are helping here on this forum.
Can some body look into this script "studentsCleaner.sh" whats wrong with this? It is working ok for all other students except shani and neetu.
[root@Lib ~]# cat /etc/cron.daily/studentsCleaner.sh
# Clean student files that is older than 30 days
# This ignores the following students as they have special lengths of time to live.
# Simon - keep for a year!
# Elaine - never delete
# Ali - keep for 60 days
# Armand - 90 days
# Max - 15 days
# Shani - 75 days
# Neetu - 100 days
find /opt/tomcat/students/ -type f -daystart -mtime +30 -not -path '/opt/tomcat/students/simon*' -not -path '/opt/tomcat/students/elaine*' -not -path '/opt/tomcat/students/ali*' -not -path '/opt/tomcat/students/armand*' -not -path '/opt/tomcat/students/max*' -not -
path '/opt/tomcat/students/neetu*' -not -
path '/opt/tomcat/students/shani*' -exec rm {} \;
# All above is one command
Infact it was working fine for all students, I inserted some new enteries for shani and neetu. Script is still running fine for other students but it is deleting files of shani and neetu older than 30 days.
I have checked the paths and the names are correct but unable to understand why the 30 days older files of shani and neetu are being deleted when i have mentioned to exclude the shani and neetu files in the first part and then clearly stated the length of these two students below.
I would really appreciate if someone can fix this issue.
Bonus points if you can use a variable for each user that indicates their file age. This way, you can use a loop with just a single parameterized find. Triple the points by creating a way to simply create a variable and have the script automatically exclude the special users from the first find, and create the second finds.
Also, DON'T exec for each and every file! Remove the -exec and instead use xargs:
Code:
find ... -print0 | xargs -0 rm -f
Guess what... not A and not B and not C is the same as not (A or B or C). This makes your find logic simpler.
jschiwal took the time to respond, yet you didn't answer the question or show that you paid much attention to the response. You won't get much help this way.
In the future, please post code in [ code ] ... [ /code ] blocks. You can also split a long line by adding a "\" at the end of a line
to keep it from being a mile long.
There is a form of using find that you might want to consider:
Code:
find ./ -maxdepth 1 -type f \( -name "*.txt" -exec ls -l '{}' \; \) -o \
\( -name "*.mp4" -exec ls '{}' \; \)
This allows you to apply different tests resulting in different actions. I also like to format code, if possible, so that it resembles a table. Imagine a case where you have an external drive or a public share filled with different types of files by different owners. You could run a script with a command like this to move files into each users respective home directory in places such as Documents/pictures/ and Documents/text/. Since each user in on another line, adding or removing a user is easy. However, using a variable in the find command and having the users listed at the top or included (sourced) from a separate file would be a better idea, if the action where the same.
Bonus points if you can use a variable for each user that indicates their file age. This way, you can use a loop with just a single parameterized find. Triple the points by creating a way to simply create a variable and have the script automatically exclude the special users from the first find, and create the second finds.
Also, DON'T exec for each and every file! Remove the -exec and instead use xargs:
Code:
find ... -print0 | xargs rm -f
Guess what... not A and not B and not C is the same as not (A or B or C). This makes your find logic simpler.
jschiwal took the time to respond, yet you didn't answer the question or show that you paid much attention to the response. You won't get much help this way.
================
Thanks for reply. You are right i should define the variables to simplify the script and definitely i will do that. but my question was why shani and neetu's 30 days older files are being deleted while i have specified to exclude them in the first find command. why the first find command doesnt exclude the shani and neetu directories? I am unable to understand why its behaviour is different for different students? see it is excluding simon, elaine, ali files.
"In your first find you use '/opt/tomcat/students/neetu*', but in your later find, you use "/opt/tomcat/output/neetu/". Same with shani."
Sorry, consider students {/opt/tomcat/students/} instead of output.
find /opt/tomcat/students/ -type f -daystart -mtime +30 -not -path '/opt/tomcat/students/simon*' -not -path '/opt/tomcat/students/elaine*' -not -path '/opt/tomcat/students/ali*' -not -path '/opt/tomcat/students/armand*' -not -path '/opt/tomcat/students/max*' -not -
path '/opt/tomcat/students/neetu*' -not -
path '/opt/tomcat/students/shani*' -exec rm {} \;
# All above is one command
At this point, it might be best to show actual evidence, by way of showing the exact command and exact output. Show the files that are incorrectly deleted and their timestamps.
At this point, it might be best to show actual evidence, by way of showing the exact command and exact output. Show the files that are incorrectly deleted and their timestamps.
=========
I really appreciate that you are helping me to fix this issue.
Sorry I didnt get you the command/script i have already pasted and I am pasting it again, I just coppied it from console
Create test data that you can test your script (or slightly modified version). This is where those variables I mentioned above comes in handy.
Use touch with the -t option to create files with old dates; some < 30 days, some > 30 but less than 75 or 100 days, and some over 75 or 100 days (depending upon the user shani or neetu). You can run ls -l of those files, show the output, run your script, and show ls -l after the script completes. The absence of files > 30 days would prove the case. Alternatively, so that you don't have to keep re-creating test days, place echo in front of your rm command so that your find just prints out what it would do.
You've been given hints and help about how to modify your script to aid YOU in debugging, and yet you're not following any advice. I can't tell where lines break because of pasting, or because you have explicitly broken them in your script. I see nothing that indicates the script fails in the way you say it does. Help yourself by following the advice of people who have years and years of experience.
I dislike really long cmd lines, they get messy & tricky to debug, as mentioned.
I'd loop over all students with a std find cmd and then just 'continue' if current 'student' is an exception, then deal with those later as you have. http://www.tldp.org/LDP/abs/html/loopcontrol.html
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.