1

I am using Windows 10.

I have many same named folders (suppose the name "data") in different subdirectories of a base directory (here "d:\dir").

How can I delete the content (containing only files) of all the folders named "data" without deleting themselves?

E.g. for three folders:

d:\dir\data
d:\dir\tmp1\data
d:\dir\tmp3\tmp2\data
1

From within a Windows command prompt window the following command line can be used to delete just all files (not folders) in all data directories of D:\dir and its subdirectories:

for /F "delims=" %I in ('dir "D:\dir\*data" /AD /B /S 2^>nul ^| findstr /E /I /C:"\data"') do @del /A /F /Q "%I\*"

The same command line would be written as follows in a Windows batch file:

@echo off
for /F "delims=" %%I in ('dir "D:\dir\*data" /AD /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /E /I /C:"\data"') do del /A /F /Q "%%I\*"

The command FOR executes in a separate command process started with %ComSpec% /C in background the command line:

dir "D:\dir\*data" /AD /B /S 2>nul | C:\Windows\System32\findstr.exe /I /E /C:"\data"

The environment variable ComSpec is usually defined as %SystemRoot%\System32\cmd.exe as it can be seen on looking on the system environment variables in Windows Control Panel - System - Advanced system settings - Environment Variables.... The environment variable SystemRoot is defined by default with path to Windows directory. In other words FOR executes by default on most Windows PCs C:\Windows\System32.exe with option /C and the command line specified between (' and '). See also Wikipedia article with a list of predefined Windows Environment Variables.

The command DIR outputs to handle STDOUT (standard output)

  • in bare format because of option /B
  • just names of directories because of option /AD (attribute directory)
  • with full path because of option /S
  • matching the wildcard pattern *data
  • in specified directory D:\dir
  • and all its subdirectories also because of option /S.

DIR would output an error message to handle STDERR (standard error) on no directory entry matching these criteria. This error message is suppressed by redirecting it to device NUL with 2>nul.

So the output of DIR is for given example:

D:\dir\data
D:\dir\tmp1\data
D:\dir\tmp3\tmp2\data

The output of DIR to handle STDOUT is redirected with | to handle STDIN (standard input) of next command FINDSTR.

FINDSTR searches in stream read from STDIN line by line

  • case-insensitive because of option /I
  • the literally interpreted string \data
  • which must be found at end of a line because of option /E.

So FINDSTR outputs to handle STDOUT of background command process all lines with \data at end of line which is for the given example again:

D:\dir\data
D:\dir\tmp1\data
D:\dir\tmp3\tmp2\data

Filtering output of command DIR with FINDSTR is necessary to exclude a directory with a name like MyData which is also output by DIR because of wildcard * which is required to get not output all subdirectories of D:\dir\data and its subdirectories, but all data directories in D:\dir and its subdirectories.

Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul and |. The redirection operators > and | must be escaped with caret character ^ on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line in a separate command process started in background.

FOR with option /F captures everything output finally to handle STDOUT of started command process and processes this output line by line after termination of started cmd.exe.

Empty lines are always ignored by FOR, but there are not empty lines output by DIR and FINDSTR.

FOR ignores by default also all lines starting with a ; which is the default end of line character. But all lines captured by FOR start in this case never with a semicolon because of all lines start with D:. So the default eol=; can be kept. Otherwise eol=| is usually the best on processing a file/folder names list as no file/folder name can contain the vertical bar.

FOR would split up by default every line into substrings using normal space and horizontal tab character as string delimiters and would assign just first space/tab separated string to specified loop variable I. A folder name in path of a data directory could contain a space character. For that reason an empty list of delimiters is specified with delims= which disables line splitting behavior resulting in getting assigned to loop variable I always the full qualified name of a found data folder.

FOR executes for every data directory assigned to I the command:

del /A /F /Q "%I\*"

%I is replaced before execution of DEL by full qualified directory name assigned currently to loop variable I.

The command DEL is for deleting files. It does not delete directories. The option /A is used to delete all files independent on their attributes including files with hidden attribute set which DEL would not delete without option /A. The option /F is required to force also a deletion of a file with read-only attribute set which would not be deleted without option /F. The option /Q is used to suppress the query asking user if really all files matched by * should be deleted by DEL.

The full qualified directory name must be enclosed in double quotes because it could contain a space or one of these characters &()[]{}^=;!'+,`~ which requires the usage of " around an argument string of a command as explained by help of CMD on last help page which is output on running in a command prompt window cmd /?.

Please note that DEL can't delete files on which the user as no NTFS permissions to delete files or which are currently opened by an application in a manner which prevents the deletion of the file while being opened by the application. DEL outputs an error message for every file which cannot be deleted due to missing NTFS or file access permissions.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • del /?
  • dir /?
  • echo /?
  • findstr /?
  • for /?
1

Following your example, you'd have to call:

Get-ChildItem -Recurse d:\dir | Where-Object { ($_.DirectoryName) -and (Split-Path $_.DirectoryName -Leaf) -eq 'data' } | Remove-Item
1

Recursively enumerate all folders with the name "data", then delete their content.

$base_dir = 'D:\dir'
$name     = 'data'

Get-ChildItem $base_dir -Recurse -Force | Where-Object {
    $_.PSIsContainer -and
    $_.Name -eq $name
} | Select-Object -Expand FullName | ForEach-Object {
    Remove-Item "$_\*" -Recurse -Force
}

In PowerShell v3 and newer you can replace the filter condition $_.PSIsContainer by using the parameter -Directory with Get-ChildItem.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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