### `tree` source code (add to your `$PROFILE`, for instance; PSv4+):
function tree {
<#
.SYNOPSIS
Prints a directory's subtree structure, optionally with exclusions. #'
.DESCRIPTION
Prints a given directory's subdirectory structure recursively in tree form,
so as to visualize the directory hierarchy similar to cmd.exe's 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.
If -IncludeFiles is also specified, the exclusions are applied to the files'
names as well.
.PARAMETER IncludeFiles
By default, only directories are printed; use this switch to print files
as well.
.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 items in the output; by default, they're ignored.
.NOTES
Directory symlinks are NOT followed, and a warning to that effect is issued.
.EXAMPLE
tree
Prints the current directory's subdirectory hierarchy.
.EXAMPLE
tree ~/Projects -Ascii -Force -Exclude node_modules, .git
Prints the specified directory's 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,
[switch] $IncludeFiles
)
# Embedded recursive helper function for drawing the tree.
function _tree_helper {
param(
[string] $literalPath,
[string] $prefix
)
# Get all subdirs. and, if requested, also files.
$items = Get-ChildItem -Directory:(-not $IncludeFiles) -LiteralPath $LiteralPath -Force:$Force
# Apply exclusion filter(s), if specified.
if ($Exclude -and $items) {
$items = $items.Where({ $name = $_.Name; -not $Exclude.Where({ $name -like $_ }, 'First') })
}
if (-not $items) { return } # no subdirs. / files, we're done
$i = 0
foreach ($item in $items) {
$isLastSibling = ++$i -eq $items.Count
# Print this dir.
$prefix + $(if ($isLastSibling) { $chars.last } else { $chars.interior }) + $chars.hline * ($indentCount-1) + $item.Name
# Recurse, if it's a subdir (rather than a file).
if ($item.PSIsContainer) {
if ($item.LinkType) { Write-Warning "Not following dir. symlink: $item"; continue }
$subPrefix = $prefix + $(if ($isLastSibling) { $chars.space * $indentCount } else { $chars.vline + $chars.space * ($indentCount-1) })
_tree_helper $item.FullName $subPrefix
}
}
} # function _tree_helper
# Hashtable of characters used to draw 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 to draw the tree.
_tree_helper $literalPath
}
这并不是一个完整的答案,但应该可以让你用一点工作来完成你想要的。如果你使用PowerShell Community Extensions中的Show-Tree代码作为基础,然后添加一些东西来过滤文件夹,你就可以完成你想要的。这应该是完全可行的,真的。因为这段代码显示了如何定义要排除的字符串(-like中接受通配符),然后获取递归文件夹结构并指示它是被排除的文件夹还是包含在被排除的文件夹中。
3条答案
按热度按时间9fkzdhlc1#
标准
tree.com
实用程序 * 不 * 支持排除目录。以下是PowerShell函数
tree
的源代码,该函数模拟tree.com
命令的行为,同时:注:您可以指定多个名称,以
,
分隔,并且这些名称可以是通配符模式-请注意,它们仅适用于目录 * name *,但不适用于完整路径。注意:请确保使用UTF-8编码 * 和BOM * 保存脚本,以便脚本在没有
-Ascii
的情况下正常运行。-IncludeFiles
以同时打印 * 文件 *。加载以下函数后,所需的命令如下所示:
有关详细信息,请运行
tree -?
或Get-Help tree
。注:
Get-PSTree
cmdlet(例如,可通过Import-Module PSTree -Scope CurrentUser
安装)提供了功能更全面的实现,特别是包括报告(累积)目录 * 大小 *(尽管在撰写本文时不支持 * 排除 * 目录)。km0tfn4u2#
在Powershell中,只需要使用Where-Object并排除你想要的文件夹名(在前面放一个
*
通配符,因为很难知道在文件夹名的同一行上有多少个空格和特殊字符):tree /A | Where-Object {$_ -notlike "*node_modules"} > tree.txt
编辑:这不会排除子文件夹,但它只会排除你的名字在Where-Object子句。
0tdrvxhp3#
这并不是一个完整的答案,但应该可以让你用一点工作来完成你想要的。如果你使用PowerShell Community Extensions中的
Show-Tree
代码作为基础,然后添加一些东西来过滤文件夹,你就可以完成你想要的。这应该是完全可行的,真的。因为这段代码显示了如何定义要排除的字符串(-like
中接受通配符),然后获取递归文件夹结构并指示它是被排除的文件夹还是包含在被排除的文件夹中。当我对我的用户配置文件运行这个命令时,它显示它捕获了一个'Temp'文件夹和一个'Template'文件夹,并标记了这些文件夹和它们的每个子文件夹要排除。您应该能够通过执行以下操作获得
Show-Tree
命令的代码:然后,您只需要设计如何将类似于我上面所做的东西合并到代码中,您就可以创建一个新函数来完成您想要的任务。