rm -i and deleting files from an index table

Hi, I am trying to make a command to delete my files out the trash can, but one at a time.

I am currently using rm - i to do this, but the original file locations for restoring my files are heard on a .txt file which I am using as an index table.

How would I manage to make it so that if I remove a file using rm - i, the original path location is removed from my FileLocations.txt file aswell?

I so far have tried using ls dustbin > dustbin.txt to have a copy of the files in a textfile that still exist, and then I was going to try compare the files and remove the lines that did contain any of the file names in my dustbin.txt file.

The problem is I don't really know how to do this, hope you can help, thanks. :slight_smile:

ls dustbin >list.ini
ls dustbin | xargs rm -i
ls dustin | grep -vf - list.ini >removed.txt
cp -p FileLocations.txt FileLocations.tmp
grep -vf removed.txt FileLocations.tmp >FileLocations.txt
rm removed.txt FileLocations.tmp list.ini

Hi, thanks for the post, I sort of understand what it is supposed to do but when it tries to do the rm -i it is doing it on simply say *file* instead of /root/dustbin/file, trying to mess about with the code but all I got was it asking me the three things quickly without getting to press y or n, and then it simply once again said can't remove file no such directory.

cd dustbin
ls >list.ini
ls | xargs rm -i
ls | grep -vf - list.ini >removed.txt
cp -p FileLocations.txt FileLocations.tmp
grep -vf removed.txt FileLocations.tmp >FileLocations.txt
rm removed.txt FileLocations.tmp list.ini
1 Like

Hey, thanks again, it almost works now just there is a problem that when it prompts the rm -i, there is no chance for input it just displays for all the files

rm:remove regular file `file.txt`? Rm:remove regular file `file2.txt`?#

And gives no oppunrtinity to press yes. Do I need to insert some sort of break?

cd dustbin
ls >list.ini
exec 3<list.ini
while read -u3 a
do rm -i $a
done
exec 3<&-
ls | grep -vf - list.ini >removed.txt
cp -p FileLocations.txt FileLocations.tmp
grep -vf removed.txt FileLocations.tmp >FileLocations.txt
rm removed.txt FileLocations.tmp list.ini
1 Like

Thank you very much for your help, it now works perfectly. :slight_smile: :b:

EDIT: Changed a few things to fix the couple of errors but thanks a lot for your help once again.

You can prevent list.ini from being listed in itself :

cd dustbin
ls | grep -v list.ini >list.ini
exec 3<list.ini
while read -u3 a
do rm -i $a
done
exec 3<&-
ls | grep -vf - list.ini >removed.txt
cp -p FileLocations.txt FileLocations.tmp
grep -vf removed.txt FileLocations.tmp >FileLocations.txt
rm removed.txt FileLocations.tmp list.ini

You can also just generate that file somewhere else so it will not be listed in that directory :

cd dustbin
ls >/tmp/list.ini
exec 3</tmp/list.ini
while read -u3 a
do rm -i $a
done
exec 3<&-
ls | grep -vf - /tmp/list.ini >removed.txt
cp -p FileLocations.txt FileLocations.tmp
grep -vf removed.txt FileLocations.tmp >FileLocations.txt
rm removed.txt FileLocations.tmp /tmp/list.ini

Thanks, I just editted where the dustbin.ini thing was saved to be in root instead of dustbin and it also worked :slight_smile:

Now got this working perfectly, thanks a bunch!

in fact you have 2 choices :
1) prevent list.ini to be listed in itself
2) put list.ini somewhere else so it doesn't appear in the dustbin list
(see my previous post that i meanwhile have updated)

Another problem i've realsied is that if I created two files with similiar names such as:

hello
hellothere

if I restored "hello" then "hellothere" also gets removed from file locations, i realise it is probbably to do with inserting a $ somewhere to make it so that what is check is hello only without any proceeding characters.

Thanks in advance.

You should replace

ls | grep -vf - /tmp/list.ini >removed.txt

by this

ls | grep -vf - /tmp/list.ini | sed 's/.*/^&$/' >removed.txt

So this will also match beginning and end of line.

The thing you have to care of is the PATH since the matching must be exact.
(a same filename can be present in 2 differents path)

So i would advise you to work with absolute path name instead of relative (unless you are certain that the filenames in dustbin are going to be uniq by design or by the way they are generated so that they can be used as a key to retrieve the original location)

how would you manage the case :

/etc/file1 
/opt/file1
/usr/file1

have been removed...

(is there only 1 corresponding file1 in your dustbin directory ? even if those files have different content to eachother ? )
Or are the dustbin filenames generated so that they are uniq ?

I have made it so all file names are unique, so for instance if there's a file in the trashcan called file then I can not send another file called file there, without removing the first instance.

I tried that code out and got the error

sed: -e expression #1, char 8: unterminated 's' command

Please post exactly what you did try (there is no "-e" option in the current version of my previous post) make sure you didn't forgot the last separator (here, a slash) in the substitution command s/.../.../

ls | grep -vf - /root/dustbin.ini | sed 's/.*/^&$/' > removed.txt

I then tried appending it to

ls | grep -vf - /root/dustbin.ini | sed 's/.*/^&$/g' > removed.txt

Then no errors were detected but it did not delete any file locations at all.

It left both:

/root/helloworld 
/root/hello

Think I should be editting it to perhaps not have an s at start but have a d at end perhaps? Just about to try that out.

You don't need the 'g' since you replace the whole line, the replacement should occure only once (so no need of 'g' option)

Show me how look the corresponding entries of these 2 files in your FileLocation.txt

What convention/rule did you choose to "make the name uniq" in dustbin.ini ?

they just are

"/root/hello
/root/helloworld" 

in FileLocations.txt.

Not sure if I made them unique in dustbin.ini, I just used the code

ls > /root/dustbin.ini

I first changed to the directory dustbin of course.

 
http://img208.imageshack.us/img208/2006/mycode.png

Edit again: Oh and I have the s at start of code just removed it for trying something but its actually there.

Why don't you just :

exec 3</root/FileLocations.txt
while read -u3 a
do rm -i $a
[[ -f "$a" ]] && echo "$a" >>/anywhere/remaining.txt
done
exec 3<&-
cat /anywhere/remaining.txt >/root/FileLocations.txt
rm /anywhere/remaining.txt

This code assume /root/FileLocations.txt contains absolute filenames (just like in your example)

Well i got it working now by editting some stuff about I think it was not deleting because of the ^ so it expected it to be at the start but really what was always going to be infront of it was a slash so I changed the ^ to \ / and it worked :slight_smile:

Will try that other code to see how it goes as well though, and if you want can let you know how it goes?

No you got it wrong : you need that ^
try your script with the list the 6 files below:

/root/helloworld
/root/world
/root/hello
/roothello
/rootworld
/roothelloworld

.... you see what i mean ? :wink: