Joseph John
Joseph John

Reputation: 520

How to delete all files except the ones with a specific pattern OR a specific type?

I have a script (executed periodically via cron) that downloads the latest version of WhatsApp from their server. I would like to retain just the latest version with the filename WhatsApp_x.x.xx in my server with a softlink latest.apk.

#!/bin/bash

 # Get the local version
oldVer=$(ls -v1 | grep -v latest | tail -n 1 | awk -F "_" '{print $2}' | grep -oP ".*(?=.apk)")

# Get the server version
newVer=$(wget -q -O - "$@" whatsapp.com/android | grep -oP '(?<=Version )([\d.]+)')

# Check if the server version is newer
newestVer=$(echo -e "$oldVer\n$newVer" | sort -n | tail -n 1)

#Download the newer versino
[ "$newVer" = "$newestVer" ] && [ "$oldVer" != "$newVer" ]  && wget -O WhatsApp_${newVer}_.apk http://www.whatsapp.com/android/current/WhatsApp.apk || echo "The newest version already downloaded"

#Delete all files that not is a new version
find  ! -name "*$newVer*"  ! -type d  -exec rm -f {} \;

# set the link to the latest
ln -sf $(ls -v1 | grep -v latest| tail -n1) latest.apk

This is how my /var/www/APK looks like:

/var/www/APK$ tree
.
├── latest.apk -> WhatsApp_2.12.96_.apk
├── script.sh
└── WhatsApp_2.12.96_.apk

But this command:

find  ! -name "*$newVer*"  ! -type d  -exec rm -f {} \;

It's also deleting the script.sh file. How can I modify the statement to not affect other files? I can't think of anything.

This is the cronjob, if that helps:

* * * * * sh /var/www/APK/script.sh

Upvotes: 1

Views: 125

Answers (2)

glenn jackman
glenn jackman

Reputation: 246799

find /var/www/APK -type f -name '*.apk' -print | 
sort -V | 
tail -n +2 | 
xargs echo rm

That finds the .apk files under the particular directory,
sorts them by version (may require GNU sort),
removes all but the newest version from the list,
and shows you which ones will be removed.

If you're satisfied it's finding the right files, take out echo


Taking a different approach: I'm going to assume that all the APK files are in the same directory, and that the filenames do not contain whitespace.

#!/bin/bash
shopt -s extglob nullglob
cd /var/www/APK
apk_files=( printf "%s\n" !(latest).apk | sort -V )
newest=${apk_files[0]}
for (( i=1; i < ${#apk_files[@]}; i++ )); do
    echo rm "${apk_files[i]}"
done
ln -f -s "$newest" latest.apk

Upvotes: 0

Tom Fenech
Tom Fenech

Reputation: 74605

With find, you can chain together multiple conditions of the same type. This leaves you with a couple of options:

You could blacklist other specific files, like this:

find  ! -name "*$newVer*" ! -name 'script.sh' ! -type d  -delete

Or just whitelist the .apk extension:

find -name '*.apk' ! -name "*$newVer*" ! -type d  -delete

Upvotes: 1

Related Questions