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
9
  • you mean that, if the init.py is outside a "migrations" folder, it can be deleted? Jun 9, 2016 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, 2016 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, 2016 at 3:29
  • @JohnAnkanna check please updated post Jun 9, 2016 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? Jun 9, 2016 at 3:50

3 Answers 3

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
4
  • Thanks, new command for me truncate. Jun 9, 2016 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, 2016 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, 2016 at 14:32
  • Cheer @muru, my lazy eyes struck again!
    – Arronical
    Jun 9, 2016 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)
2
  • Thanks for suggestion, but I'd like to have command line solution. I have already script in python which does this function, I upvoted your answer. Thanks for your effort. gist.github.com/MichaelPavlov/a1394fca9a4a0228a2dcc12427121f5a Jun 9, 2016 at 5:36
  • @МихаилПавлов just call the script from the command line? You can even pass command line arguments as target folder and target file.
    – Ajasja
    Jun 9, 2016 at 11:15
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.

1
  • Your first command is almost certainly using an extended glob. Zsh?
    – muru
    Jun 9, 2016 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.