Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
                        rm "$i/*";

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

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"
share|improve this answer
Hi 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


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

Warning, if you have the following tree:


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
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
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .