Print directory tree but exclude folder on windows cmd
cmd.exe
Internal command tree
does not support directory exclusion.
-
If you only need to exclude directories on behalf of yourself and also not all of their subtree (child directories and their descendants), see nferrell's answer .
-
If you need to exclude all directory subtrees that match a given name , you need more work - see below.
Below is the source code for a PowerShell function tree
that emulates the behavior of the command cmd.exe
tree
, plus:
- proposal to selectively exclude subtrees by name
Note. You can specify multiple names, separated by a character,
, and the names can be wildcard patterns - note that they only apply to the directory name, not the full path. - cross-platform support
Note. Make sure to save the script with UTF-8 encoding with the BOM for the script to work properly without-Ascii
.
When loading the function below, the loaded command looks like this:
tree -Exclude node_modules -Ascii > tree.txt
Run tree -?
or Get-Help tree
for more information.
tree()
source code (add for example yours $PROFILE
, PSv4 +):
function tree {
<#
.SYNOPSIS
Prints a directory subtree structure, optionally with exclusions. #'
.DESCRIPTION
Prints a given directory subdirectory structure recursively in tree form,
so as to visualize the directory hierarchy similar to cmd.exe built-in
'tree' command, but with the added ability to exclude subtrees by directory
names.
NOTE: Symlinks to directories are not followed; a warning to that effect is
issued.
.PARAMETER Path
The target directory path; defaults to the current directory.
You may specify a wildcard pattern, but it must resolve to a single directory.
.PARAMETER Exclude
One or more directory names that should be excluded from the output; wildcards
are permitted. Any directory that matches anywhere in the target hierarchy
is excluded, along with its subtree.
.PARAMETER Ascii
Uses ASCII characters to visualize the tree structure; by default, graphical
characters from the OEM character set are used.
.PARAMETER IndentCount
Specifies how many characters to use to represent each level of the hierarchy.
Defaults to 4.
.PARAMETER Force
Includes hidden directories in the output; by default, they're ignored.
.NOTES
As of v5.1, v6 beta, PowerShell handling of symlinks is lacking.
Therefore, directory symlinks are ignored for now.
.EXAMPLE
> tree
Prints the current directory subdirectory hierarchy.
.EXAMPLE
> tree ~/Projects -Ascii -Force -Exclude node_modules, .git
Prints the specified directory subdirectory hierarchy using ASCII characters
for visualization, including hidden subdirectories, but excluding the
subtrees of any directories named 'node_modules' or '.git'.
#>
[cmdletbinding(PositionalBinding=$false)]
param(
[parameter(Position=0)]
[string] $Path = '.',
[string[]] $Exclude,
[ValidateRange(1, [int]::maxvalue)]
[int] $IndentCount = 4,
[switch] $Ascii,
[switch] $Force
)
# Embedded recursive helper function for drawing the tree.
function _tree_helper {
param(
[string] $literalPath,
[string] $prefix
)
# Get all subdirs.
$dirs = Get-ChildItem -LiteralPath $literalPath -Directory -Force:$Force
# Apply exclusion filter(s), if specified.
if ($Exclude -and $dirs) {
$dirs = $dirs.Where({ $name = $_.Name; $Exclude.ForEach({ $name -like $_ }) -notcontains $True })
}
if (-not $dirs) { return } # no subdirs., we're done
$i = 0
foreach ($dir in $dirs) {
$isLastSibling = ++$i -eq $dirs.Count
# Print this dir.
$prefix + $(if ($isLastSibling) { $chars.last } else { $chars.interior }) + $chars.hline * ($indentCount-1) + $dir.Name
# Recurse.
if ($dir.LinkType) { Write-Warning "Not descending into symlink: $dir"; continue }
$subPrefix = $prefix + $(if ($isLastSibling) { $chars.space * $indentCount } else { $chars.vline + $chars.space * ($indentCount-1) })
_tree_helper $dir.FullName $subPrefix
}
} # function _tree_helper
# Hashtable of characters used to represent the structure
$ndx = [bool] $Ascii
$chars = @{
interior = ('├', '+')[$ndx]
last = ('└', '\')[$ndx] #'
hline = ('─', '-')[$ndx]
vline = ('│', '|')[$ndx]
space = ' '
}
# Resolve the path to a full path and verify its existence and expected type.
$literalPath = (Resolve-Path $Path).Path
if (-not $literalPath -or -not (Test-Path -PathType Container -LiteralPath $literalPath) -or $literalPath.count -gt 1) { throw "'$Path' must resolve to a single, existing directory."}
# Print the target path.
$literalPath
# Invoke the helper function
_tree_helper $literalPath
}
source to share
This is not quite a complete answer, but should allow you to accomplish what you want with a little work. If you've used Show-Tree
code from the PowerShell community Extensions as a basis, and then add in something to filter folders, you can do whatever you want. This is something that should be completely doable, in fact, as this little code shows how to define a string to exclude (wildcards accepted in the format -like
), then get a recursive folder structure and indicate if it is an excluded folder, or contained in excluded folder.
$DirExcludes = @()
$ToExclude = 'temp*'
GCI -Recurse -Directory |%{
Switch($_){
{$_.Name -ilike $ToExclude} {
$DirExcludes += $_.FullName;
Write-Host $_.FullName -ForegroundColor Red
Continue}
{$DirExcludes -and $_.FullName -match "^($(($DirExcludes|%{[regex]::Escape($_)}) -join '|'))"} {
Write-Host $_.FullName -ForegroundColor DarkRed
Continue
}
default {Write-Host $_.FullName -ForegroundColor Blue}
}
}
When I ran this against my user profile, it showed that it caught the Temp folder and the Template folder, and tagged them and every subfolder of those to be excluded. You should get the command code by Show-Tree
running:
Get-Command Show-Tree -ShowCommandInfo | % Definition
Then you just need to figure out how to include something similar to what I have in this code and you can make a new function to do what you want.
source to share
In Powershell, just use Where-Object and exclude the folder names you want (put the wildcard *
in front, as it can be difficult to know how many spaces and special characters are on the same line as the folder name):
tree /A | Where-Object {$_ -notlike "*node_modules"} > tree.txt
Edit: This does not exclude subfolders, but it only excludes the folders you specify in the Where-Object clause.
source to share