Python os.walk: how to delete directories after its sub-directories are all deleted - directory

I have a multi-layer directory. I want to start from the lowest level directories and delete all empty directories. My current code doesn't delete higher-level directories that become empty after their sub-directories are all deleted becuase os.walk supposedly doesn't update the path? How should I modify it so that it updates root each time?
for root, dirs, files in os.walk(starting_directory, topdown=False):
if not files and not dirs:
shutil.rmtree(root)

This script will do the job. Goes to the very bottom of a directory tree... is the directory empty? yes? then delete and goes up from there. Good for cleaning empty folders.
#!/usr/bin/python
"""
*
* This python script removes empty directories using a bottom-up approach.
* It can be run from your present directory and it will remove all directories that are
* completely empty - working from the lowest levels -- up to your present directory.
"""
import os
for root, dirs, files in os.walk(".", topdown=False):
for name in files:
print(os.path.join(root, name))
for name in dirs:
print("...in for name in dirs", name)
print(os.path.join(root, name))
if len(os.listdir(os.path.join(root, name))) == 0:
print("Directory is empty... deleting")
os.rmdir(os.path.join(root, name))
else:
print("Directory is not empty")

Related

UNIX: how to zip a folder that contains more folders w/o including any of the folder paths

I' m trying to zip a folder that contains some .json files plus subfolders with more .json files. I need to zip the parent folder with everything included without containing any of the parent or subfolders paths. Is there any way I can do this?
Thank you
EDIT:
I want this:
pending_provider/722c9cb2-268b-4e4a-9000-f7f65e586011-version/1d296136-ac87-424e-89c4-682a63c7b853.json (deflated 68%)
But not this:
pending_provider/722c9cb2-268b-4e4a-9000-f7f65e586011-version/ (stored 0%)
I want to avoid the "stor" compression type which only saves the folder path. I want only the "defN"
So the -j doesn't help me a lot
Thanks
If you don't want any paths at all you could use the -j option. Below is the man page entry for the option.
-j
--junk-paths
Store just the name of a saved file (junk the path), and do not store
directory names. By default, zip will store the full path (relative to
the current directory).
If you just want to exclude directories
-D
--no-dir-entries
Do not create entries in the zip archive for directories.

How to stop git (.gitignore) from tracking minqueue (wordpress plugin) cached changes

After entering "git status", I keep getting messages like wp-content/uploads/minqueue-cache/minqueue-9cbb4cb4-9cb6af13.js
even though I have added the following line to .gitignore file: /wp-content/uploads/minqueue-cache/*
. Why is this?
The slash in the beginning of /wp-content/uploads/minqueue-cache/* means starting from the directory where the .gitignore file is in, so your pattern will match all files and folders inside wp-content/uploads/minqueue-cache/ but not the files inside www.apis.de/wp-content/uploads/minqueue-cache/.
If you change the pattern to wp-content/uploads/minqueue-cache/* it will match all files and folders in all wp-content/uploads/minqueue-cache/ folders, no matter where they start.
If you change the pattern to /www.apis.de/wp-content/uploads/minqueue-cache/* it will match all files and folders exactly in this one directory.

Are the period commands "." and ".." actually referencing a file?

Since everything in Unix is a file, when we call "cd ." are we actually cding into the directory . ? Is it a protected symbolic reference to the parent directory of each directory?
Yes, everything in Unix, is a file. Like any directory, a file of any type, any device(speaker, keyboard,. etc.) and even a file-system itself, all act like a file for OS. In Unix every file has a inode attached with it, which contains the file metadata like info about permissions, size, time-stamps and most importantly file data block pointers which point to data block containing actual file data.
Hence each Directory(being a file) also has a inode. The content of the directory is the sequence of records. Each record has at least two fields which are filename and the inode number.
file1name file1_inode_number
Exact structure of record depends on the filesystem implementation. So basically directory file contain a (record)entry corresponding to each file and immediate sub-directory inside it. In addition to that, Directory file also contain 2 more entries which are
. : mapped with self inode
and
.. : mapped with parent's inode
so all over directory structure looks like
. inode_number_of_self
.. inode_number_of_parent_dir
file1name inode_number_of_file1
file2name inode_number_of_file2
.
.
so on
So whenever you cd ./ or cd ../ OS is referring current or parent directory(respectively) relative to your current directory.

nsis adds empty folders to the installer

The File below:
; Install common files
SetOutPath "${GameDir}\Mopy"
File /r /x "*.bat" /x "*.py*" /x "w9xpopen.exe" /x "Wrye Bash.exe" "Mopy\*.*"
filters out some directories that contain python files but still those directories are created (although empty, or containing empty subdirectories) when I run the installer. Those folders need to be included to the installer (if I get the terminology correct at "compile time") cause the installer has an option to install the python version of the program. I can't come up with a way to not add these empty folders. Is there some wildcard I could use to that purpose or should I go and remove the files on installation (using RMDir ?) ?
I'd say you have two options and one is indeed RMDir if you are OK with it possibly removing empty folders that the user created.
The other option is to not use File /r ... and instead use !system to execute something like a batch file that generates a text file with individual File instructions that you can !include. It would look something like this:
!tempfile files
!system '"mygeneratefilelist.bat" "${files}"'
!include "${files}"
!delfile "${files}"
and the batch file would use FOR and/or DIR to list and ECHO the File commands to %1...

7zip command line - recursively unzipping all zipped files

I have 7zip on my desktop computer, at: c:\program files\7-zip\7z.exe. I also have 2 mapped drives that have similar structures, drive X and drive Y. Below is an example of the source.
Drive X
X:\Sourcefolder\Folder1\file1.zip
X:\Sourcefolder\Folder1\file2.zip
X:\Sourcefolder\Folder2\file3.zip
X:\Sourcefolder\Folder3\file4.zip
The destination folder structure would be as follows:
Drive Y
Y:\DestFolder\Thing1\Folder1\[file1.zip contents and subfolders]
Y:\DestFolder\Thing1\Folder1\[file2.zip contents and subfolders]
Y:\DestFolder\Thing1\Folder2\[file3.zip contents and subfolders]
Y:\DestFolder\Thing1\Folder3\[file4.zip contents and subfolders]
The folders on Drive Y (DestFolder\Thing1\Folder1, 2 & 3) are already created. Some of them may already have other files & subfolders in them.
I can run the following command line and unzip the contents:
for /R %i IN (*.zip) DO "c:\program files\7-zip\7z.exe" x "%i" -o"Y:\DestFolder\Thing1\Folder1"
However, what happens is that on my mapped drive, I see a NEW structure out there that is exactly what I had in the second set of quotes in the command line, even if those folders already existed. Thus far, I've only tested it on empty folders, as I am concerned it might corrupt any existing files that would be there. I can navigate between them, and can cut & paste the files into the correct folder.
Why is 7zip "creating" the duplicate folder structure to extract the files into? I know the -o switch allows you to specify a destination directory, but it doesn't say in the help file that it creates it or what happens if it already exists.
Should I be using another command line parameter to extract these zip files into the proper folders? Thanks!

Resources