I want to develop a script for deleting files older than x days from multiple paths. Now I could reach upto this piece of code which deletes files older than x days from a particular path. How do I enhance it to have an input from a .txt file or a .dat file? For eg: For deleting *.csv files older than Num_days, I am using below piece of code:
cd $FILEPATH
find ./ -type d ! -name . -prune -o -mtime +$Num_days -name "*.csv" -exec rm {} \;
You could read the paths from the file using a while loop. Then call find once per path, substituting the value read into the find command twice, as the path argument and the argument to the first -name predicate.
There are several ways to do this. Assuming there are no whitespace characters in any of the directory names in the list of directories in your text file, the following is probably the shortest:
If there might be space or tab characters in directory names:
saveIFS="$IFS"
IFS=""
while read dir
do find "$dir" -type d ! -name . -prune -o -mtime +$Num_days -name "*.csv" -exec rm {} \;
done < dirlist.txt
IFS="$saveIFS"
If there are any newline characters in the directory names in your list, you have my sympathy and will not be able to use anything that has a newline separated list of directories (i.e., a text file) to store the directory list.
Using read's -r option is a good idea for this application, and just setting IFS for the read is also fine.
Depending on what I'm doing, I frequently just set IFS="" at the start of a script knowing that it won't affect the invoking shell execution environment. I saved and restored it here in case someone runs this code without putting it in a subshell environment; but just setting it for read has the same effect.
read -r reads raw. If backslash escape sequences occur in your input, they will not be interpreted. E.g., if the input has \n , it will be treated as \n and not as a new-line. You'll get the input as is with no such interpretation by read .
For the same code, I have an additional requirement. How can we have 2 parameters passed from the input file dirlist.txt? The two parameters would be 1. Teh directory path 2. The retention days
In short , now I wanna write a script taht would delete files older than the retention period. This period should be different for different directory paths. Till now I have written this piece of code.
while IFS= read -r d; do
(
cd "$d"
files2del=`ls *.dat `
if [ ${files2del:-NO} = "NO" ]
then
echo " No files to delete" | mailx -s " ATTENTION: NO FIES TO DELETE " $EMAILLIST
else
find "$d" -type d ! -name . -prune -o -mtime +$NUM_DAYS -name '*.dat' -print
echo " Files to delete : $files2del " | mailx -s " Files deleted are from path $d " $EMAILLIST
fi
)
done < dirlist.txt
The dirlist.txt can have sample input as
/path1 7
/path2 4
/path3 9
wherein 7,4 and 9 are retention days for which the files have to be kept and the files older than these should be deleted.
Hi,
One more requirement for the same code. Along with the two parameters in the input file, I want to add one more parameter i.e. file extension. This parameter will be different for different paths.
Th input file will now look like this:
/path1 7 *.dat
/path2 4 *.csv
/path3 9 *.txt
For this, my command goes like this:
while IFS=' ' read -r dir NUM_DAYS file_extn; do
(
files2del=$(find . -type d ! -name . -prune -o -mtime +$NUM_DAYS -name '$file_extn' )
echo "$files2del" >> $LOGFILE 2>&1
)
done < dirlist.txt
The problem is , it is not listing any file in the output. Can anyone please let me know where am I going wrong?