5

I want to create a shell script that will count files (1 hr older files) and if files are more than 1000, then delete all.

For read and delete I am using those command at putty

for count:

ls /tmp/ | grep 'ci_session*' | wc -l

for Delete files:

cd /tmp/
find . -name "ci_session*" -exec rm {} \;

#Update: for delete, i want to delete only 1 hr older files.

Here I want to add condition if total files are greater than 1000, then call delete command.

  • 1
    Why not parse ls? – Cyrus Mar 23 at 18:12
  • Greater than 1000 what? Lines long? Bytes? Or are you wanting to delete only if there are more than 1000 files? – Kusalananda Mar 23 at 18:13
  • Are you okay with "Older than 1 hour" meaning last modified greater than 1 hour ago? Unix operating systems generally don't have a concept of creation time – Jesse_b Mar 23 at 18:13
  • @Kusalananda number of files. – Yogesh Saroya Mar 23 at 18:14
7

I interpreted your question as "How may I count the files, and if there are more than 1000, delete the ones that are older than one hour?".

Counting the names matching /tmp/ci_session* and doing something when there's more than 1000 of them:

set -- /tmp/ci_session*
if [ "$#" -gt 1000 ]; then
    # something
fi

This sets the positional parameters to the names matching the pattern. The special variable $# then contains the number of positional parameters.

Deleting the files matching /tmp/ci_session* if their last modified time is more than an hour ago:

find /tmp -maxdepth 1 -type f -name 'ci_session*' -mmin +60 -delete

Taken together:

#!/bin/sh

set -- /tmp/ci_session*
if [ "$#" -gt 1000 ]; then
    find /tmp -maxdepth 1 -type f -name 'ci_session*' -mmin +60 -delete
fi

The only thing to note here is that the count will be of any name matching the pattern (even of directory names, if there are any), while the find command will restrict the deletion to only regular files (i.e. not directories).

  • I thought set would surely fail with "argument list too long" at some point, but no. I guess because set is a built-in? – l0b0 Mar 23 at 21:57
  • @l0b0 Exactly. Built-in utilities do not have any restrictions like that, and set is furthermore a special built-in utility, which means it needs to always be built into the shell (or it would not be able to set positional parameters nor shell options). – Kusalananda Mar 23 at 22:03
  • I am getting this error. /bin/bash: /home/yogeshs/public_html/cleanup.sh: Permission denied i added sh file at public_html folder then added cron job (* * * * * /home/yogeshs/public_html/cleanup.sh ) – Yogesh Saroya Mar 24 at 4:54
  • @Kusalananda pls help getting Permission denied – Yogesh Saroya Mar 24 at 5:09
  • @YogeshSaroya Either run the script with sh scriptname or make it executable with chmod +x scriptname and run it as you're trying to now. – Kusalananda Mar 24 at 7:03
5

As long as your find has an -mmin option you can do:

Using a shell script:

#!/bin/sh

files_dir=/tmp
file_count=$(find "$files_dir" -name 'ci_session*' -mmin 60 -exec echo x \; | wc -l)

if [ "$file_count" -gt 1000 ]; then
    find "$files_dir" -name 'ci_session*' -mmin 60 -exec rm {} \;
fi

file_count will be set to the number of files found in the specified directory matching the pattern.

If file_count is greater than 1000 we will run find again and delete those files.


Using bash we can eliminate the second call to find with an array:

#!/bin/bash

files_dir=/tmp
mapfile -t files < <(find "$files_dir" -name 'ci_session*' -mmin 60)

if ((${#files[@]}>1000)); then
    rm "${files[@]}"
fi

Note: depending on how many files you expect to have the bash solution may run into your command line argument limit.

  • could you please update delete command to delete only 1hr older files ? – Yogesh Saroya Mar 23 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.