-   Linux - Newbie (
-   -   For loop to delete all RPMS except for RPMS on the list. (

keysorsoze 05-20-2008 10:09 AM

For loop to delete all RPMS except for RPMS on the list.
Hi! I have a problem trying to delete extra rpms from a directory /cdrom/RedHat/RPMS/ which will be used to perform
a kickstart install via CDROM. The directory consist rougly around 1500 RPMS that we can slim down to around 300
required packages.

My goal is to pipe in a file "/var/log/rpmpkgs" and only keep those files since they were used to perform the install
and all dependencies will be resolved. As for the rest of the files we can remove all of them. I am stuck at how to
perform a loop that will save the rpms from /var/log/rpmpkgs but delete the 1300 rpms that remain.

Here are my awful attempts please advise on what I am doing wrong and how to exclude packages from a file.

Attempt #1

for i in `ls -l | awk '{ print $9 }'` do rm -i < /var/log/rpmpkgs

Attempt #2

find . -type f -exec rm -rf < /var/log/rpmpkgs \;

/var/log/rpmpkgs is a list of files on the system so they should remain.


MensaWater 05-20-2008 11:07 AM


for file in ls
do if grep $file /var/log/rpmpkgs >/dev/null 2>&1
  then echo "File $file is in /var/log/rpmpkgs so is NOT being deleted."
  else echo " Deleting file $file."
        rm $file

You don't need the -l flag of ls if all you want is the file name. Simple ls will give you the names only. (On display these wrap but in scripts it gets them properly - you can force single list on display with the -1 [one] option.)

The if tests whether the file you have exists in the /var/log/rmppkgs file. If so it doesn't do anything except tell you it is not being deleted. If not it tells you it is being deleted then deletes it.

Use this at your own risk as I haven't tested it here. I'd suggest creating a test directory and file to test a few files on before doing this on your main directory.

bigrigdriver 05-20-2008 11:16 AM

There are probably more elegant ways than this to do it, but here's my offering.


for i in /cdrom/RedHat/RPMS/*; do
    for j in /var/log/rpmpkgs/*; do
        if [ -e "$i" -a -e "$j" ]; then
            mv $j /path/to/keeper-files/

rm /var/log/rpmpkgs/*

For each file in the first directory, compare it to every file in the second. If you find a match, move it to another (temporary) location.

Keep looping until all files in the first location have been compared to every file in the second location, with all matches moved for safekeeping.

Then remove the remainder.

You can flesh out the code to move the saved files back to the original location.

Edit: lightner thinks more elegantly than I do, and types faster than I do. I like his solution better than mine.

colucix 05-20-2008 12:01 PM

Another solution is to compare the actual listing with the content of /var/log/rpmpkgs, print the differences and remove them

rm $(comm -3 <(ls -1 *.rpm) <(sort /var/log/rpmpkgs))
provided that the output of ls -1 is comparable to the content of /var/log/rpmpkgs.

keysorsoze 05-20-2008 12:29 PM

Thanks, jlightner, and bigrigdriver for your input your scripts worked!. I tweaked jlightner's script and it worked like a charm. Here is the modified script for those who are interested:

for file in `ls`
do if grep $file /var/log/rpmpkgs >/dev/null 2>&1
then echo "File $file is in /var/log/rpmpkgs so is NOT being deleted."
else echo " Deleting file $file."
rm $file

I initially ran the script in the /cdrom/RedHat/RPMS directory and the script got blown away too. You might want to modify the script to just do a ls of the /cdrom/RedHat/RPMS directory.

Thanks for the help I have been banging my head for a couple of hours on this.

MensaWater 05-20-2008 03:42 PM

Oops - my apologies for leaving out the back ticks. Now you know why I told you to test it first. Glad you figured it out.

All times are GMT -5. The time now is 01:09 PM.