3

Assume that I have a directory structure as follows:

application
│
├── config
│   ├── c1.conf
│   └── c2.conf
│
├── logs
│   ├── l1.txt
│   └── l2.txt
│
└── src
    ├── static
    ├── s1.py
    └── s2.py

Now I want to delete all the folders except config and logs (in this case, only src). my PWD is currently a parent of appliaction/ dir (i.e. I can see application in my PWD).

What command should I use? (I tried with rm -rf with some options but mistakenly deleted other files, so I would like to know the correct answer before trying anything else!)

4 Answers 4

8

Try find ./application/ -type d -not -name config -not -name logs.

If that returns the proper directories, run

find ./application/ -type d -not -name config -not -name logs -exec rm -R {} \;

The exec rm -R {} \; at the end removes the directory even if it is not empty.

1
  • Warning: This deletes all sub-directories, too. Jan 9, 2015 at 16:59
1

This way is a little more work than some other possible solutions, but when I'm deleting files I like to be able to double check what's going away forever. The steps below assume you can see "application" in your PWD, as stated in your question.

First create a new text file containing the names of every folder you want to keep (not delete), with one folder per line. Save it as to-keep.txt for example:

config
logs

Then copy the following into a text editor and save it as rm-exclude.sh so that all three files are in the same directory.

#!/usr/bin/env bash

find "./$1" -maxdepth 1 -type d ! -path "./$1" > to-delete.txt

dels=`cat to-delete.txt`
readarray -t keeps < to-keep.txt

for keep in "${keeps[@]}"; do
    dels=`echo "$dels" | grep -v "$keep"`
done

echo "$dels" > to-delete.txt

Make it executable using:

chmod +x rm-exclude.sh

Then run it with the following, where PATH is the path to the "application" folder from your PWD. In your example, PATH would simply be application.

./rm-exclude.sh PATH

Finally, check to-delete.txt to make sure nothing is getting deleted that shouldn't be, and run:

readarray -t dels < to-delete.txt; for del in "${dels[@]}"; do rm -rf "$del"; done

If you don't care about checking the contents of the txt file, you can simply copy and paste the above command to the end of rm-exclude.sh so that running the script does everything as long as you have to-keep.txt already filled out. The end result should be that every direct subfolder of application not in to-keep.txt will be deleted, along with their contents.

1

Based on Jos's answer, I use this to delete all files and directories in the current directory only, except for the .git directory.

sudo find /home/jeffy/django_files/djauth_lifecycle_tutorial/part_04/ -maxdepth 1 -mindepth 1 -not -name .git -exec rm -rf {} \;

I actually got scared and thought this deleted the .git directory as well, but I just forgot to use the a flag with la (ls -la).

The mindepth flag is to avoid deleting the root directory itself. The -maxdepth prevents all sub-directories and files from being returned, which are redundant with the f flag.

(Also, never use relative paths when using rm -r!)

0

What I will do with my shell (zsh) is the following (but I think that with bash ther is something equivalent).

  1. Type

    echo application/*(/) 
    

and, without hitting return, press TAB.

  1. the shell will expand the pattern glob; in this case, a list of all directories under application; the line should be now

    echo application/config application/logs application/src
    
  2. Now I would edit the line to remove the directories I want to maintain.

  3. I triple check and edit the initial echo to rm -rf.

  4. I check again and...

  5. ...hit return.

Anyway, that kind of task (selecting by hand files or folders to apply action to them) is really better done with some kind of visual aid, unless you are a command-line "nerd" like myself... for example people is really fond of Midnight Commander.

You must log in to answer this question.

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