Home > OS >  Script to remove older files from various directories
Script to remove older files from various directories

Time:06-17

I want to remove files(whose name contains "extract") older than 7 days from various directories in a particular path. If I run the script without any argument the script should be able to delete the files from all the directories inside that particular path. If I run the script using any arguments , then the script should not delete files from those specific directories.

Example :-

Path - /languages/analytics

Let's assume directory "analytics" contains 10 dirctories like c,java,javascript,python,shell,golang,scala,ruby,react,angular.This directory also contains few files along with these 10 directories.

Scenario1 - I want to remove the files older than 7 days from all the 10 directories.

Scenario2 - I want to remove the files older than 7 days from all directories except angular.

Scenario3 - I want to remove the files older than 7 days from all directories except ruby,react,shell.

So basically whatever arguments I pass , the script should not delete files from those particular directories.The number of arguments may vary as per requirement.And if I run without arguments, then the script should delete older files from all the directories in that path.The number of directories may vary as well.

Here is what I have written so far ...

#!/bin/bash

cd /languages/analytics
for f in *; do
    if [ -d "$f" ] && [[ "$f" != $1 ]]; then
        find /languages/analytics/"$f" -mtime  7 -name '*extract*' -exec rm -f {} \;        
    fi
done

The above script works fine when I run it without arguments. It runs fine when I pass 1 argument.

sh scriptname -> successfully deletes files from all directories in /languages/analytics path.

sh scriptname ruby -> successfully delete files from all directories except ruby.

Can you please advise how to enhance this script to take as many arguments as possible and the script should not delete files from those particular directories which are passed in the argument ?

CodePudding user response:

With GNU find try

# /usr/bin/env bash
root=/languages/analytics
exclude=(-name ..) # always FALSE, neutral element of OR 
for arg; do
  exclude =(-o -samefile "$root/$arg")
done
find "$root" \( "${exclude[@]}" \) -prune -o -mtime  7 -name '*extract*' -delete

For testing you might want to leave out the -delete first.

For different version of find, you can use the -exec rm -f {} instead of -delete and try -path instead of -samefile. But beware! -path interprets patterns like * and ? and fails to recognize that ruby, ruby/ and are the same thing. But for plain arguments like script.sh ruby golang you should be fine.

CodePudding user response:

Try this Shellcheck-clean code:

#! /bin/bash -p

for dir in /languages/analytics/*/; do
    for arg; do [[ $dir == */"$arg"/ ]] && continue 2; done
    find "$dir" -mtime  7 -name '*extract*' -exec rm -f {} \;
done
  • for arg; do loops over the positional arguments ($1, $2, ...)
  • continue 2 skips to the next iteration of the outer (for dir ...) loop.

CodePudding user response:

#!/bin/bash

args=("${@}")

mainpath=./languages/analytics
readarray -t datafolders < <(find "$mainpath" -maxdepth 1 -mindepth 1 -type d -print0|xargs -0 -I {} basename {})

for subfolder in "${args[@]}"; do
  for i in "${!datafolders[@]}"; do
    if [[ ${datafolders[i]} = "$subfolder" ]]; then
      unset 'datafolders[i]'
    fi
  done
done

datafolders=( "${datafolders[@]/#/$mainpath/}" )

declare -p datafolders


# delete command for multiple folders 
# find "${datafolders[@]}" -type f -mtime  7 -name '*extract*' -print0 | xargs -0 rm -f

For my test i used "./languages/analytics"

Scenario 1 all directories

$ ./script.sh
declare -a datafolders=([0]="./languages/analytics/ruby" [1]="./languages/analytics/react" [2]="./languages/analytics/scala" [3]="./languages/analytics/java" [4]="./languages/analytics/angular" [5]="./languages/analytics/javascript" [6]="./languages/analytics/python" [7]="./languages/analytics/shell" [8]="./languages/analytics/golang" [9]="./languages/analytics/c")

Scenario 2 except angular

$ ./script.sh angular
declare -a datafolders=([0]="./languages/analytics/ruby" [1]="./languages/analytics/react" [2]="./languages/analytics/scala" [3]="./languages/analytics/java" [4]="./languages/analytics/javascript" [5]="./languages/analytics/python" [6]="./languages/analytics/shell" [7]="./languages/analytics/golang" [8]="./languages/analytics/c")

Scenario 3 except ruby react shell

$ ./script.sh execpt ruby react shell
declare -a datafolders=([0]="./languages/analytics/scala" [1]="./languages/analytics/java" [2]="./languages/analytics/angular" [3]="./languages/analytics/javascript" [4]="./languages/analytics/python" [5]="./languages/analytics/golang" [6]="./languages/analytics/c")
  •  Tags:  
  • bash
  • Related