Not sure whether This belongs here but...

L Carver

New Member
Joined
Sep 29, 2018
Messages
4
Reaction score
2
Credits
0
.. I have a Bash script meant to look for backup files (suffixed with .bak or ~). I also have an if..then routine (?) to write the names of the files found with those suffixes to a text file.
The text of the script is as follows:
Code:
#!/bin/bash


files1=$(find . -type f -name "*bak*")
if [ -e "$files1" ];
then
 /bin/rm -v  "$files1" 2>/dev/null
   echo -e "All backup files ending in *bak removed.\nNames written to log file."
    echo "$files1" >> cleanback.log
fi
files2=(*~)
if [ -e "$files2" ];
then
  /bin/rm -v  "$files2"
   echo -e "All backup files ending in ~ removed.\nNames written to log file"
    echo "$files2" >> cleanback.log
fi

I had a previous draft of the script that used a "find / xargs exec " routine, but adapting it to print the items found to a text file failed to work. In changing it to use just find, it fails to find all files matching the criteria ant thus I have to run it multiple times to remove all the matching files.

Help!

Carver
Edit: My Linux is Kubuntu, version 17.04 but I plan an upgrade in the next month or so.
My hardware is a Dell Inspiron 1720, 200GB HDD, 2GB Ram
 


Hi @L Carver and welcome to linux.org :)

I've moved this over to Command Line, where scripting enquiries are placed, so that it may attract more attention to assist you.

Avagudweegend

Chris Turner
wizardfromoz
 
It is possible to use a single find command to search for files based on multiple criteria.

But before we go into that "*bak*" would be a BAD choice of pattern for removing .bak files. Because that pattern would match any file with a name that has "bak" anywhere in it.
e.g.:
If you had a file containing your wifes favourite baked potato recipes called:
wifes_baked_potato_recipes.txt
The pattern "*bak*" would find, match and delete that file alongside any .bak files that were present.
So you need to be careful when using globbing characters like * to search for files.
What characters normally come after the .bak part of the filename? There may be a way to extend the regex to find those files too!

To use find to find all .bak (or .BAK) files AND all files ending with ~ - You could change your find command to:
Code:
files1=$(find ./ -type f \( -iname '*.bak' -o -name '*~' \))

And that should locate all .bak, .BAK and ~ files in a single search. You'd be able to completely remove the block of code containing the 2nd search from your script.



Taking things further using aliases:
If you wanted to, you could perform find, delete and log all in one single command, which you could set up as an alias.

For example - I have a couple of aliases set up in my .bashrc for cleaning up backup files:
Code:
alias rrmb='find ./ -type f \( -iname "*.bak" -o -name "*~" -o -name "#*#" \) -delete'
alias rmb='find ./ -maxdepth=1 -type f \( -iname "*.bak" -o -name "*~" -o -name "#*#" \) -delete'
rrmb is used to recursively find and remove backup files in the current directory and all sub-directories
rmb is used to find and remove backup files in the current directory without recursing into sub-directories.
NOTE: The 3rd pattern ('#*#') is for cleaning up backup files from emacs. Despite being a vim user, I do occasionally use emacs!



In my aliases - I don't bother logging a list of deleted backup files. But they could be expanded to facilitate logging in a number of slightly different ways.....

e.g.

Adding the -print option to find would simply print the list of deleted files on the screen:
Code:
alias rrmb='find ./ -type f \( -iname "*.bak" -o -name "*~" -o -name "#*#" \) -print -delete'
alias rmb='find ./ -maxdepth=1 -type f \( -iname "*.bak" -o -name "*~" -o -name "#*#" \) -print -delete'



By adding output redirection to the version above, we could make the command silently find and delete files and append the list of deleted files to a log-file in the current users home directory:
Code:
alias rrmb='find ./ -type f \( -iname "*.bak" -o -name "*~" -o -name "#*#" \) -print -delete >> ~/deletedfileslog'
alias rmb='find ./ -maxdepth=1 -type f \( -iname "*.bak" -o -name "*~" -o -name "#*#" \) -print -delete >> ~/deletedfileslog'

NOTE: In the above aliases, we are using the append operator >> to redirect find's output to the log-file. So the list of deleted files will be appended to the end of the specified file, if it already exists. If it does not exist, the file is created before the output is appended to it.
If you only want the logfile to contain the list of files for the most recent run, you could change >> to >. This will cause the aliases to clobber the old file and create a fresh log-file each time.




Finally, if we remove the output redirection and pipe find's output to tee instead - we can print the list of files to the screen AND redirect the list to a logfile:
Code:
alias rrmb='find ./ -type f \( -iname "*.bak" -o -name "*~" -o -name "#*#" \) -print -delete | tee -a ~/deletedfileslog'
alias rmb='find ./ -maxdepth=1 -type f \( -iname "*.bak" -o -name "*~" -o -name "#*#" \) -print -delete | tee -a ~/deletedfileslog'

NOTE: the -a option will cause tee to append data to the end of the specified file. If the file does not already exist - it is created. Without -a, tee would completely re-write the file.
So if you only want the log to contain information from the most recent run, simply remove the -a option from the above aliases.

I hope this helps!
 
Last edited:

Members online


Top