Create output file w/ empty folder - Delete empty directories

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

Create output file w/ empty folder - Delete empty directories

Post by MigrationUser »

{Merge of two similar threads about Deleting unused directories}

22 Feb 2011 03:12
rubyroseveloso

Hi!

I need to determine empty folders within a given file location (e.g. C:\test\) and output the empty folder file names to an output file (e.g. C:\test\output.txt).

I have this code for the batch file however I can only echo ALL the folders to the txt file. I only need the empty folder file names to be echoed.

Code: Select all

pushd C:\test
for /d %%d in (*) do (
rd /q %%d
echo %%d >> c:\test\output.txt
)
popd
Can someone assist me with this?

Thanks!

----------------------------

#2 22 Feb 2011 10:35
RG

Here's one way to do what you are asking. (You did not mention empty subfolders and this does not check for those).

Code: Select all

pushd C:\test
set OutFile=output.txt
if exist %OutFile% DEL /q %OutFile%

for /d %%d in (*) do CALL :IsDirEmpty "%%d" && ECHO.%%d >> %OutFile%

popd
goto :eof

:: [url]https://ritchielawrence.github.io/batchfunctionlibrary/[/url]
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:IsDirEmpty %dir%
::
:: By:   Ritchie Lawrence, 2003-09-22. Version 1.0
::
:: Func: If specified directory is empty of files and directories, then
::       errorlevel is set to zero. If directory is not empty or does not
::       exist, errorlevel is non-zero one. For NT4/2000/XP/2003.
:: 
:: Args: %1 Name of directory to be tested (by val)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
setlocal ENABLEEXTENSIONS & dir/ad %1 >nul 2>nul || (endlocal & goto :EOF)
set i=0 & for /f %%a in ('dir %1/a/b 2^>nul') do set/a "i+=1"
md;2>nul & (if %i%==0 ver>nul) & endlocal & goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Last edited by RG (22 Feb 2011 10:36)

Windows Shell Scripting and InstallShield

----------------------------

#3 22 Feb 2011 10:41
allal

Code: Select all

@echo off>output.txt
pushd C:\test 

for /d %%a in (.) do (
dir /b "%%~a" | find /v "" >nul ||echo empty folder detected & rd /q "%%~a" &echo "%%~a" >>output.txt)

popd
Last edited by allal (22 Feb 2011 12:13)

----------------------------

#4 22 Feb 2011 10:47
bluesxman

With that code, this is all you need to do:

Code: Select all

@echo off
type nul >c:\test\output.txt
pushd C:\test
for /d %%d in (*) do (
rd /q "%%~d" && echo "%%~d" >> c:\test\output.txt
)
popd
Last edited by bluesxman (22 Feb 2011 15:47)

cmd | *sh | ruby | chef

----------------------------

#5 22 Feb 2011 11:15
allal
bluesxman wrote:

With that code, this is all you need to do:

Code: Select all

@echo off
    type nul >c:\test\output.txt
    )
    pushd C:\test
    for /d %%d in (*) do (
    rd /q "%%~d" && echo "%%~d" >> c:\test\output.txt
    )
    popd
i think you will log and remove all directories empty and non empty

Last edited by allal (22 Feb 2011 11:16)

----------------------------

#6 22 Feb 2011 15:45
bluesxman

It will only remove empty directories and will only report those it successfully removes (by virtue of the "&&"). That is the code as originally submitted with a couple of small tweaks. I made the assumption from that code that removing the directories and reporting those which were removed was the intended goal.

Last edited by bluesxman (22 Feb 2011 15:46)

cmd | *sh | ruby | chef

----------------------------

#7 23 Feb 2011 00:57
rubyroseveloso

It worked! thank you very much! :)

----------------------------

#8 23 Nov 2015 21:45
tinog

Hi everyone

I created a short script that deletes all empty subdirectories in the directory it is called.
It works perfectly fine, except with directories with spaces, f.e. "new folder".

Putting quotes around it helps in the cmd, but somehow not in my batch-file.
Does anybody know how to fix this?

Here's the code:

Code: Select all

@ECHO OFF
:: Deletes all empty subfolders in current directory

:: Preconditions, temp_dir.txt and temp_rev.txt mustn't_exist
if exist temp_dir.txt goto :error
if exist temp_rev.txt goto :error
if exist dont_care.txt goto :error

for /D /r %%g in (**) do echo %%g >> temp_dir.txt
revert temp_dir.txt temp_rev.txt
for /F %%g in (temp_rev.txt) do rmdir %%g 2> dont_care.txt
del dont_care.txt
del temp_dir.txt
del temp_rev.txt

goto :after

:error
echo "temp_dir.txt or temp_rev.txt or dont_care.txt exists"
echo "THEY MUST NOT!"
goto :after

:after

If you wonder what reverse is, it's a simple program that takes a text input, and puts it out with all the lines reversed.
This helps first delete the child-subdirectories before deleting their parent-subdirectories, which wouldn't work the opposite way.
The source (for the interested ones) is here:

/*
 * @Input argv[1]: sourcefile
 * @Input argv[2]: destination
 * @description: This program takes a file of any tipe
 *  and flips all the lines. It is thought for files with
 *  text, but would work on any file.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct linked_str {
	char* str;
	struct linked_str* previous;
};

/*
char* savedup(const char* source)
{
	int i = 0;
	char* destination = NULL;
	while(source[i] != '\0') {
		i++;
	}
	destination = malloc(++i);
	if (destination) {
		strncpy(destination, source, i);
	}
	return destination;
}
*/

int main(int argc, char** argv)
{
	FILE* fin;
	FILE* fout;
	
	char single;
	char temp[65536];
	unsigned int j = 0;
	struct linked_str begin = {NULL, NULL};
	struct linked_str* curlstr = &begin;
	struct linked_str* prevlstr = NULL;
	
	// Preconditions
	if (argc < 3) {
		fprintf(stderr, "Enter input & output file path\n");
		return 1;
	} else
	if (argc > 3) {
		fprintf(stderr, "Can only process two filepaths\n");
		return 1;
	}
		
	fin = fopen(argv[1], "r");
	
	while(!feof(fin)) {
		// Readline while not empty or error
		if (!fgets(temp, 65536, fin)) break;
			
		// puts(temp);
		if (!(curlstr->str = strdup(temp))) {
			fprintf(stderr, "strdup memory error\n");
			return 2;
		}
		prevlstr = curlstr;
		curlstr = (struct linked_str*)malloc(sizeof(linked_str));
		curlstr->previous = prevlstr;
	}
	fclose(fin);
	// Here, curlstr->str is NULL and curlstr->previous is set
	free(curlstr);
	curlstr = prevlstr;
	
	fout = fopen(argv[2], "w");
	
	int i = 1;
	
	while (curlstr->previous != NULL) {
		fputs(curlstr->str, fout);
		if (i) {
			if (!strchr(curlstr->str, '\n')) {
				fputc('\n', fout);
			}
			i = 0;
		}
		// puts(curlstr->str);
		free(curlstr->str);
		prevlstr = curlstr->previous;
		free(curlstr);
		curlstr = prevlstr;
	}
	// Final fputs:
	fputs(curlstr->str, fout);
	free(curlstr->str);
	fclose(fout);
	
	return 0;
}
----------------------------

#9 23 Nov 2015 22:57
foxidrive

This is an alternative. Remove the echo statement after testing and add 2>nul to hide the harmless error messages.

Code: Select all

@echo off
for /f "delims=" %%a in ('dir /b /s /ad ^| sort /r ') do echo rd "%%a"
pause
Last edited by foxidrive (23 Nov 2015 22:58)

----------------------------

#10 24 Nov 2015 23:04
tinog

Wow. You just condensed a script + an executable in basically one line.
Thank you very much
Post Reply