Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I got a folder that has a whole bunch of subdirectories.

I need to delete all of them EXCEPT folders that has a marker file say example: DONOTDELETE.txt inside the said folders.

Is this possible?

Already had a presolution Thanks to Benoit

( find /testftp -type d ;
  find /testftp -type f -iname DONOTDELETE.TXT -printf '%h'
) | sort | uniq -u | while read i
                     do
                        rm "$i/*";
                     done

but the output is:

rm: cannot lstat `/testftp/*': No such file or directory

rm: cannot lstat `/testftp/logs/*': No such file or directory

share|improve this question
    
Yes, it's possible. Are you expecting one of us to write it for you? –  Nifle Feb 23 '12 at 16:26
    
Just asking for help Nifle. that would really be appreciated if you can give me an idea on this. Kinda new to scripting to be honest –  JoyIan Yee-Hernandez Feb 23 '12 at 16:27
    
Start looking at what find can do. Use that in conjunction with dirname to find all dirs you want to leave alone. –  Nifle Feb 23 '12 at 16:33
    
Update your question (or better yet delete this one and ask a new) when/if you get stuck or have a partial solution. –  Nifle Feb 23 '12 at 16:36

3 Answers 3

find . -type f ! -name DONOTDELETE.txt  -print0 | xargs -0 ls -l
share|improve this answer
    
Thanks for the input Zab. –  JoyIan Yee-Hernandez Feb 23 '12 at 16:44
2  
No, that will list files of which the name is different, but will still list files in the same directory. –  Benoit Feb 23 '12 at 17:01
    
Yes. I'm trying to get a hang of the find command. I tested this out and yeah it still lists the files that I wanted to keep. I'm playing around it and wanting for the specific folder to not exist on the ls -l and wanting to expect that folder that contains DONOTDELETE.txt won't come up –  JoyIan Yee-Hernandez Feb 23 '12 at 17:03
    
Rephrase question again and more and more people will jump in to help.... –  ZaB Feb 24 '12 at 8:28

As shell fragment:

for i in *; do
     [ -d "$i" ] || continue # ignore non-directories
     [ -f "$i/DONOTDELETE.txt ] && continue  # ignore directories containing DONOTDELETE
     rm -rf "$i"
done
share|improve this answer
    
Hi Jakob...im new to scripting..can you explain further? :) –  JoyIan Yee-Hernandez Feb 23 '12 at 19:32
    
I'm confused at the moment lol... –  JoyIan Yee-Hernandez Feb 23 '12 at 21:42
    
Sorry for the delay :) –  jakob Feb 24 '12 at 11:45
    
Every unix shell descended from the original bourne shell has control flow statements - while, for, if/else etc. In this case, for is used. * expands to a list of files, and the for body is executed for every file. "[" is a executable (look for /bin/[). It is also available under the name "test", read "man test". -d checks whether the next thing is a directory; -f checks whether the next ting is an ordinary file. "continue" is a bash control flow construct, it behaves exactly like "continue" in java or c. –  jakob Feb 24 '12 at 11:46
    
Any more specific questions? –  jakob Feb 24 '12 at 11:50

How I would do that (maybe overcomplicated):

  • Find all dirs
  • Find all files named DONOTDELETE.TXT and print dir names
  • Sort and uniq to keep unique lines

So:

( find . -type d ;
  find . -type f -iname DONOTDELETE.TXT -printf '%h'
) | sort | uniq -u | while read i
                     do
                        rm "$i/*";
                     done

Warning, if you have the following tree:

A/foo.txt
A/b/DONOTDELETE.TXT

Then the output of this last script will still output A because it does not contain a file named DONOTDELETE.TXT.

Another way:

find . -type f ! -iname DONOTDELETE.txt -delete
find . -d -type d -empty -delete

which first nukes all files that don't have this name, and second removes empty directory (-d explores subtrees first).

share|improve this answer
    
Really confused right now...sorry for being such a newb... wanted to delete all files under /ftptest except files that doesn't have the DONOTDELETE.TXT and your code seemed to be great...just really confused ATM. so sorry –  JoyIan Yee-Hernandez Feb 23 '12 at 17:14
    
find /testftp -type f ! -iname DONOTDELETE.txt -delete <--This worked for me. I had a /testftp/logger/ which contains DONOTDELETE.TXT and test.txt, It still deleted the test.txt, would like to happen to keep test.txt I really appreciate the contribution you gave Benoit –  JoyIan Yee-Hernandez Feb 23 '12 at 17:21
    
@JoyIanYee-Hernandez can you possibly have trees like the one I showed in my answer? Directory not containing the marker, having a subdirectory containing the marker? Should foo.txt be nuked or not? –  Benoit Feb 23 '12 at 17:28
    
With this ( find /testftp -type d ; find /testftp -type f -iname DONOTDELETE* -printf '%h'; ) | sort | uniq -u I got a tree: /testftp /testftp/logs <--- this directory does not contain the DONOTDELETE.TXT this is pretty close, just need to delete all the files inside that /testftp/logs folder –  JoyIan Yee-Hernandez Feb 23 '12 at 17:36
    
So, pipe that command into while read i ; do rm "$i/*" ; done. –  Benoit Feb 23 '12 at 17:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.