How to delete all files / folders from a folder, except for several folders?

I am trying to write support scripts for a debian package. Suppose 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 files / folders except config and logs (in this case, src and lib folders and file1.txt and file2.txt files). My PWD is currently the parent of appliaction/ dir (i.e. I see application in my PWD ).

Which command should I use (small bash script will be large)? (I tried using rm -rf with some options, but deleted the other files by mistake, so I would like to know the correct answer before trying anything else!)

+6
source share
6 answers

From what I am collecting, there are a bunch of other folders besides src , because otherwise you would just use rm -rf src .

If your PWD is equal to application , that is, you are in the parent directory of config logs and src , you just need a way to use rm -rf for 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 
+1
source

This should 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 new characters 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 new characters 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 the directories below ./application , excluding those that have /config and /logs , and prints them starting at the lowest
  • xargs directory removal is performed
+1
source

Since you simply delete the application/application/src directory, there is no reason to use find, etc. All you have to do is:

 rm -rf application/application/src 

Left:

 application/application/logs/l2.txt application/application/logs/l1.txt application/application/config/c1.conf application/application/config/c2.conf 
0
source
 cd application find . -type d | egrep -v '(^\./$|^\./log|^\./config)' | while read DIR do echo rm -rf $DIR done 

This uses find to list all directories, pipes through grep, to exclude the ones we want to keep (also exclude "./" that would be PWD), and channels that filter the list in the while loop that Delete removes. I put an echo there so you can check if this does what you really want. If you are happy, delete the echo. SInce returned list (DIR) will be in tree order, for example. d1, d1 / d1a, d1 / d1b and rm -rf d1 will delete the lower folders, you can add "if [-d $ DIR]" around rm -rf.

0
source

Using Bash:

 for file in applications/*; do target="${file#*/}" if [[ $target != config && $target != logs ]]; then rm -rf "$file" fi done 
0
source

No need for complex find commands, just use the shell (if you are in the application folder):

 rm -r !(logs|config) 

This is called "Path Extension," from man bash

  !(pattern-list) Matches anything except one of the given patterns 
0
source

Source: https://habr.com/ru/post/973527/


All Articles