How to delete all the files/folders from the folder except few folders?
Asked Answered
L

6

6

I am trying to write maintainer scripts for debian package. Assume that I have a directory structure as follows:

application/
----application/file1.txt
----application/file2.txt
----application/config
--------application/config/c1.conf
--------application/config/c2.conf
----application/logs
--------application/logs/l1.txt
--------application/logs/l2.txt
----application/src
--------application/src/static/
------------application/src/static/js
------------application/src/static/css
--------application/src/s1.py
--------application/src/s2.py
----application/lib
--------application/src/js/
--------application/src/css/

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

What command should I use (a small bash script would be great)? (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!)

Lysenko answered 8/8, 2014 at 7:10 Comment(1)
What options did you try? Because you can do this with plain rm (see my answer).Equable
Z
1

From what I gather, there's a bunch of other folders other than src because otherwise you would just use rm -rf src.

If your PWD is application, i.e. you're in the parent directory of config logs and src, you just need a way to use rm -rf on all files/folders except config and log, so why not make a for loop?

    #!/bin/bash

    cd "/path/to/application"

    for file in * ; do
            case "$file" in
                    config )
                            echo "file is $file: doing nothing"
                    ;;
                    logs )
                            echo "file is $file: doing nothing"
                    ;;
                    * )
                            echo "file is $file: removing"
                            rm -rf "$file"
                    ;;
                    esac
            done
    exit 0
Zinovievsk answered 8/8, 2014 at 7:56 Comment(5)
This does not delete the files.Equable
Please check the original post under the edits. It said folders specifically. "files/folders" was added into the question after I had provided my answer. In any case, to remove the files as well, just remove the if statement from the above and provided there aren't any files named config or logs withouth any extension this script will work as intended.Zinovievsk
Ah, I hate it when people change their question that significantly. But maybe good then to remove the if-statement to keep it consistent?Equable
Sure, change made. I'm new to these forums and not so sure what the etiquette is when the original post is changed well after a correct answer is provided. If you hadn't pointed out the updated question I probably would never have checked this.Zinovievsk
Well, it is not really appreciated normally, but in this case it doesn't hurt to much. I upvoted because this solution should work, altough I think mine is better ;)Equable
R
1

This must work:

find ./application -depth -mindepth 1 -type d \
  -regextype posix-extended ! -regex ".*\/(config|logs).*" | \
  -exec rm -fr {}  \;

Or with xargs if you don't have folder names with newlines in them you can write:

find ./application -depth -mindepth 1 -type d \
  -regextype posix-extended ! -regex ".*\/(config|logs).*" | \
  xargs -t -I {} rm -fr {}

Or with xargs if you have folder names with newlines in them you can use:

find ./application -depth -mindepth 1 -type d \
  -regextype posix-extended ! -regex ".*\/(config|logs).*" -print0 | \
  xargs -0 -t -I {} rm -fr {}
  • find finds all directories below ./application excluding those that have /config and /logs and prints them starting with the lowest
  • xargs runs removing the directory
Rockaway answered 8/8, 2014 at 8:8 Comment(0)
S
0

Since you are just deleting the application/application/src dir, there is no reason to use find, etc.. All you need to do is:

rm -rf application/application/src

remaining:

application/application/logs/l2.txt
application/application/logs/l1.txt
application/application/config/c1.conf
application/application/config/c2.conf
Steeplejack answered 8/8, 2014 at 7:40 Comment(0)
E
0
cd application
find . -type d | egrep -v '(^\./$|^\./log|^\./config)' | while read DIR
do
   echo rm -rf $DIR
done

This uses find to list all the directories, pipes through grep to exclude the ones we want to keep (also to exclude "./" which would be the PWD), and pipes that filtered list to the while loop which does the delete. I've put the "echo" in there so you can test if this does what you actually want. If you're happy then remove the echo. SInce the the returned list (DIR) would be in tree order, e.g. d1, d1/d1a, d1/d1b, and rm -rf d1 would remove the lower folders, you might want to add a "if [ -d $DIR ]" around the rm -rf.

Emplace answered 8/8, 2014 at 8:17 Comment(2)
Oops, too late, my answer is along the sames as skwilsp's. He got in whilsts I was writing mine. I think his is more concise though.Emplace
Never use capitalized variables in bash, keep those reversed for system variables.Equable
E
0

Using Bash:

for file in applications/*; do
    target="${file#*/}"
    if [[ $target != config && $target != logs ]]; then
        rm -rf "$file"
    fi
done
Evocation answered 8/8, 2014 at 9:35 Comment(0)
E
0

There is no need for complicated find commands, just use the shell (assuming you are in the application folder):

rm -r !(logs|config)

This is referred to as "Pathname Expansion", from man bash

         !(pattern-list)
                Matches anything except one of the given patterns
Equable answered 14/8, 2014 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.