4

There are lots of posts where people asking how to delete files except ones, but my question is more specific. There are several folders named migrations in current directory's sub-folders, which contain __init__.py file and some more. How to delete all files except __init__.py in all sub-folders named migrations from current folder?

UPD: And is it possible to overwrite __init__.py with empty file?

Folder structure:

├── folder_1
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       ├── 0001_initial.cpython-35.pyc
│   │       └── __init__.cpython-35.pyc
├── folder_2
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       ├── 0001_initial.cpython-35.pyc
│   │       └── __init__.cpython-35.pyc
├── folder_3
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       ├── 0001_initial.cpython-35.pyc
│   │       └── __init__.cpython-35.pyc
  • you mean that, if the init.py is outside a "migrations" folder, it can be deleted? – Vitor Abella Jun 9 '16 at 2:52
  • @Vitor please check edited post, mb there are some bad grammar in my english, but I think it makes sense. – Михаил Павлов Jun 9 '16 at 2:58
  • just let us know the hierarchy of your directory structure so it will be more useful to solve your problem – Ankanna Jun 9 '16 at 3:29
  • @JohnAnkanna check please updated post – Михаил Павлов Jun 9 '16 at 3:38
  • init.py are always inside "migrations", so you just loop into files. if the file is init.py empty it, if not delete it. Am I right? – Vitor Abella Jun 9 '16 at 3:50
7

With find:

find . -path '*/migrations/__init__.py' -exec truncate -s 0 {} + -o -path '*/migrations/*' -delete

This runs find in the current directory (.), and:

  • for anything matching migrations/__init__.py, it will run the truncate command. truncate -s 0 <file> reduces the file to size 0 (empty);
  • failing that match, for anything matching migrations/*, it will delete it;
  • the * in -path matches / unlike the * in bash.

Example:

$ tree                                                                                                                                   
.
├── folder_1
│   └── migrations
│       ├── 0001_initial.py
│       ├── __init__.py
│       └── __pycache__
│           ├── 0001_initial.cpython-35.pyc
│           └── __init__.cpython-35.pyc
├── folder_2
│   └── migrations
│       ├── 0001_initial.py
│       ├── __init__.py
│       └── __pycache__
│           ├── 0001_initial.cpython-35.pyc
│           └── __init__.cpython-35.pyc
└── folder_3
    ├── admin.py
    ├── apps.py
    ├── __init__.py
    └── migrations
        ├── 0001_initial.py
        ├── __init__.py
        └── __pycache__
            ├── 0001_initial.cpython-35.pyc
            └── __init__.cpython-35.pyc

9 directories, 15 files
$ find . -path '*/migrations/__init__.py' -exec truncate -s 0 {} + -o -path '*/migrations/*' -delete                
$ tree                                                                                              
.
├── folder_1
│   └── migrations
│       └── __init__.py
├── folder_2
│   └── migrations
│       └── __init__.py
└── folder_3
    ├── admin.py
    ├── apps.py
    ├── __init__.py
    └── migrations
        └── __init__.py

6 directories, 6 files

$ wc -l */migrations/__init__.py
0 folder_1/migrations/__init__.py
0 folder_2/migrations/__init__.py
0 folder_3/migrations/__init__.py
0 total
| improve this answer | |
  • Thanks, new command for me truncate. – Михаил Павлов Jun 9 '16 at 6:38
  • +1 Pro find usage, does -o only operate on anything which isn't matched the first expression? I can only find it in the examples section of the man page. – Arronical Jun 9 '16 at 12:09
  • @Arronical yes, it's an OR. You can find it in the OPERATORS section of the manpage (right above STANDARDS CONFORMANCE). It's also part of POSIX. – muru Jun 9 '16 at 14:32
  • Cheer @muru, my lazy eyes struck again! – Arronical Jun 9 '16 at 14:34
2

Create a .py file, edit the path (directory that you will work), and compile it (python3).

  • code: delete all files on 'path' except 'target_file' inside 'target_folder', that are just clear(empty).
import os, sys
path='/home/vitor/Desktop/teste/'
target_folder='migrations'
target_file='__init__.py'

for directory, subdirs, files in os.walk(path):
    for file_name in files:
        folder_name=os.path.split(os.path.abspath(directory))[-1]
        if(folder_name==target_folder and file_name==target_file):
            open(directory+'/'+file_name, 'w').close()
        else:
            os.remove(directory+'/'+file_name)
| improve this answer | |
0

Here is a simpler command. I know some one already answered the question, but these commands should be simpler and unique. Try them to see if they work.

To remove every subfolder and file except __init__.py and displays which files have been deleted, try the following commands:

rm -rfv ./*/migrations/!(__init__.py)

To make a empty file, just add the following command in addition:

> ./*/migrations/__init__.py

The above command is just like writing empty data to a file like as follows:

/dev/null > ./*/migrations/__init__.py

Note

All these commands execute from current directory .

Precaution

Please make a backup before you try any of the commands. No one is 100% perfect in this world.

| improve this answer | |
  • Your first command is almost certainly using an extended glob. Zsh? – muru Jun 9 '16 at 14:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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