5

Using a simple batch file, compatible with the command processor in Windows 7, how can one detect if a folder has any contents (meaning one or more files or subfolders, i.e. not empty)?

I tried:

IF EXIST C:\FOLDERNAME\* GOTO ROUTINE

But this always returns TRUE and thus goes to ROUTINE.

How can this be accomplished?

4 Answers4

7
dir /A /B "C:\FOLDERNAME" | findstr /R ".">NUL && GOTO ROUTINE

If there is at least one line of output, then the directory is not empty.
The findstr /R "." results the into a successful exitcode and the && will execute the goto routine

jeb
  • 78,592
  • 17
  • 171
  • 225
user2956477
  • 1,208
  • 9
  • 17
  • Might I suggest you use the `DIR` **`/A`** option to ensure that it doesn't miss, for instance, hidden items. `DIR/B/A "C:\FOLDERNAME"2>NUL|FINDSTR .*>NUL&&GOTO ROUTINE` – Compo Apr 14 '17 at 11:08
  • Your answer tries to solve **another problem** than the question author asks. He considered **a folder with some (even empty) subfolders as nonempty**, while you are **looking only for files** (and do this recursively). While your understanding of "emptiness" also makes sense, but it differs from the question author's understanding, for him `dir /A /B "C:\FOLDERNAME" | findstr . >NUL && GOTO ROUTINE` would be enough and more correct. Also, your implementation assumes that directory names never contains `.` and file names always contain `.`, but that's not true. – Sasha Jul 24 '19 at 07:02
  • 4
    Ouch. I've noticed that [the original answer](/revisions/43409248/2) of user2956477 was fully correct, but then the Community user [changed it](/posts/43409248/revisions) in the weird way. Please, somebody, **revert to the original user2956477's version**! – Sasha Jul 24 '19 at 07:04
  • How about this code form ss64: https://ss64.com/nt/empty.html – Ricardo Bohner Jan 14 '20 at 10:52
  • At my end, **`findstr /L "."`** works with this folder name **`A.B.C`**, which contains dots. – Matthew Wai Mar 04 '20 at 11:19
  • @Sasha I reverted it to the correct answer and add an explanation – jeb Mar 16 '21 at 12:05
2

The solution I prefer is to iterate through the files in the directory and then iterate through the attributes of each file to get its size and find out if it is greater than 0.

The following script I made validates the following:

  • If the specified directory exists.
  • Whether the folder contains files or not.
  • If the folder contains files larger than 0 bytes.

In case there are no files or the files do not exceed 0 bytes, the script will report that the directory does not contain any files.

To run the script you must use the following command, where "C:/path" is the directory to check:

start name.bat "C:/path"

Rename the script and change the directory.


Bat script:

@echo off

REM Command to launch the script:
REM >> start name.bat "C:/path"

REM Check if path exist
if exist %1 (

    REM Loop in dir files
    for /f "delims=" %%f in ('dir /a /b /s %1') do (
        
        REM Check file sizes
        for /f "usebackq delims=" %%s in ('%%f') do (

            REM Check if there is a file bigger than 0 bytes
            if %%~zs GTR 0 (
                echo The directory is not empty
                goto end
            )
        )
    )
    echo The directory is empty

) else (
    echo The directory does not exist
)

:end
pause
Ariel Montes
  • 256
  • 2
  • 6
  • But if a directory contains a file, it's not empty, independent of the file size – jeb Mar 15 '21 at 16:28
  • 1
    Just remove the second `for` leaving the `echo` and the `goto` if you don't need this feature. Personally, I prefer to consider empty a folder that contains empty files. – Ariel Montes Mar 15 '21 at 16:37
  • You can only remove a directory when it's empty - there is nothing in it. Btw. Your code fails if there are files or directories beginning with `;` – jeb Mar 15 '21 at 16:40
  • To remove all the files from directories and subdirectories you can use `del /F/Q/S *.* > nul` and using special characters in file and folder names is generally considered bad practice. – Ariel Montes Mar 15 '21 at 16:46
  • 1
    `C:\Program Files (x86)`, `C:\Documents & Settings` are named by Microsoft. Btw. Even if it's bad practice, a function should always return a correct value – jeb Mar 15 '21 at 16:50
  • The fact that a boss puts his feet up on the table in his office is not an invitation to his employees to imitate him. But you are right, that is why I would not use a scripting language to perform this task, however I wanted to respond to the OP according to his need. By the way this line can be used to delete a directory, its subdirectories and all files: `rmdir path /s` – Ariel Montes Mar 15 '21 at 16:54
  • I upvoted this as a good starting point, but I think it really needs to be able to handle any valid filename, including those that start with a semicolon (or period, or any other valid character). – RockPaperLz- Mask it or Casket Mar 15 '21 at 23:51
  • Hi, I have tested it with directory `...\;test1` and detected the existence of file `...\;test1\folder;a\;New Doc.txt`. What kind of characters do you have problems with?`. – Ariel Montes Mar 16 '21 at 08:51
  • Hi Ariel. I was referring to the comment made by @jeb. Is jeb mistaken? – RockPaperLz- Mask it or Casket Mar 16 '21 at 21:29
  • @RockPaperLz-MaskitorCasket Yes, I was wrong. I missed that the `/s` option forces the `dir` command output to a full path, therefore the semicolon isn't a problem. But the `/S` isn't a good solution, it takes minutes to get `The directory is not empty` for `C:\ ` – jeb Mar 16 '21 at 22:09
  • It shouldn't take more than a few seconds, as my code stops when it finds the first file that is larger than 0 bits. – Ariel Montes Mar 17 '21 at 01:42
  • @ArielMontes But a `FOR /F` collects the complete output of the command, **before** it begins with looping. Only reading a file with FOR /F is done line by line – jeb Mar 17 '21 at 07:52
1

You can put something like this in a batch file (assuming you know the folder exists):

FOR /F %%A IN ('DIR /A /B FolderName 2^>nul') DO GOTO NonEmpty
GOTO Empty

Change /A to /A-D if you want to test whether the folder contains files (ie, ignore the subfolders).

Change /A to /AD if you want to test whether the folder contains subfolders (ie, ignore the files within the folder).

ASdeL
  • 211
  • 2
  • 6
0

Slightly different answer, but my search led here and hopefully this helps others.

My use case is I want to run an exe if the current folder has files in it. If the current folder is empty or contains only other folders, then I want nothing to happen.

I started with trying something like if exist *.??? since in my case, the files in that folder always have a three char extension... but this did not work because ? seems to match o or more, not 1 or more. It always evaluated true, even when the folder had no files in it (I assume because every folder contains folders named . and .. )

So I tried a different approach using dir. I found in my case findstr had no bearing on the result (I believe because in my case dir /A-d /b returns "file not found" if there are no files in the dir due to -D parameter on /A... so the findstr . always returns true).

In my case, the statement below worked like a charm. It executes the command if there are files in the folder and does nothing if there are no files or only other folders in the folder.

cd c:\interesting_dir
dir /a-D /b>nul && (
  c:\path\to\program1.exe
  c:\path\to\program2.exe
)