Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PowerShell计算文件夹深度_Powershell_Calculated Columns_Powershell 4.0 - Fatal编程技术网

使用PowerShell计算文件夹深度

使用PowerShell计算文件夹深度,powershell,calculated-columns,powershell-4.0,Powershell,Calculated Columns,Powershell 4.0,1。代码说明别名其工作原理 用户输入PowerShell中目录的路径。代码检查声明目录中的任何文件夹是否完全不包含数据。如果是这样的话,任何空文件夹的路径都会在提示中显示给用户,并最终从系统中删除 2。这个问题是我正在努力解决的问题 我刚才编写的代码没有像我预期的那样计算文件夹层次结构的深度(输出表中的列为空)。除此之外,该程序运行正常-我仍然需要修复我的代码先删除空的父目录,然后再删除子目录的问题,这当然会在PowerShell中导致错误;例如,以 C:\Users\JohnMiller\D

1。代码说明别名其工作原理

用户输入PowerShell中目录的路径。代码检查声明目录中的任何文件夹是否完全不包含数据。如果是这样的话,任何空文件夹的路径都会在提示中显示给用户,并最终从系统中删除


2。这个问题是我正在努力解决的问题

我刚才编写的代码没有像我预期的那样计算文件夹层次结构的深度(输出表中的列为空)。除此之外,该程序运行正常-我仍然需要修复我的代码先删除空的父目录,然后再删除子目录的问题,这当然会在PowerShell中导致错误;例如,以

C:\Users\JohnMiller\Desktop\Homework
其中,
作业
包括
作业\数学\学校项目
作业\计算机科学\ PowerShell代码
。请注意,除了包含此脚本的文件夹
PowerShell code
,所有目录都应为空。(旁注:如果文件夹中没有文件,则认为文件夹为空。至少目前我的代码是基于此。)


3。代码

# Delete all empty (sub)folders in [$path]

[Console]::WriteLine("`n>> Start script for deleting all empty (sub)folders.")
$path = Read-Host -prompt ">> Specify a path"

if (test-path $path)
{
  $allFolders = Get-ChildItem $path -recurse | Where {$_.PSisContainer -eq $True}
  $allEmptyFolders = $allFolders | Where-Object {$_.GetFiles().Count -eq 0}
  $allEmptyFolders | Select-Object FullName,@{Name = "FolderDepth"; Expression = {$_.DirectoryName.Split('\').Count}} | Sort-Object -descending FolderDepth,FullName

  [Console]::WriteLine("`n>> Do you want do remove all these directories? Validate with [True] or [False].") #'#
  $answer = Read-Host -prompt ">> Answer"

  if ([System.Convert]::ToBoolean($answer) -eq $True)
  {
    $allEmptyFolders | Remove-Item -force -recurse
  } 

  else
  {
    [Console]::WriteLine(">> Termination confirmed.`n")
    exit
  }
}

else
{
  [Console]::WriteLine(">> ERROR: [$($path)] is an invalid directory. Program terminates.`n")
  exit
}
深度计数问题: 您的代码在传递给
选择对象
的计算属性中引用了
.DirectoryName
属性,但是
[System.IO.DirectoryInfo]
Get ChildItem
输出的
实例没有此类属性。请改用
.FullName
属性:

$allEmptyFolders | 
  Select-Object FullName,@{Name='FolderDepth'; Expression={$_.FullName.Split('\').Count}} |
    Sort-Object -descending FolderDepth,FullName
消除嵌套的空子文件夹: 用一个简单的例子来重述您的问题:

如果
c:\foo
为空(无文件),但子目录为空
c:\foo\bar
,您的代码将两者都输出,如果先删除
c:\foo
,则删除
c:\foo\bar
下一步将失败(因为删除
c:\foo
也会删除
c:\foo\bar

如果删除所有嵌套的空子曲面。首先,您不仅可以将呈现给用户的内容分离出来,还可以安全地对输出进行迭代并逐个删除

使用这种方法,您需要第二步来消除嵌套的空目录,但是这里有一个深度优先递归函数,它省略了嵌套的空文件夹。要使其与代码在隐藏文件方面的行为相同,请传递
-Force

函数递归获取空目录{
[cmdletbinding()]
param(
[字符串]$LiteralPath='.',
[切换]$Force,
[开关]$DoNotValidatePath
)
$ErrorActionPreference='Stop'
如果(-not$DoNotValidatePath){
$dir=获取项-LiteralPath$LiteralPath
if(-not$dir.PSIsContainer){Throw“nota directory path:$LiteralPath”}
$LiteralPath=$dir.FullName
}
$haveFiles=[bool](获取ChildItem-LiteralPath$LiteralPath-File-Force:$Force |选择对象-第一个1)
$emptyChildDirCount=0
$emptySubdirs=$null
if($childDirs=Get ChildItem-LiteralPath$LiteralPath-Directory-Force:$Force){
$emptySubDirs=新对象System.Collections.ArrayList
foreach($childDir中的$childDirs){
if($childDir.LinkType-eq'symbolicink'){
编写详细的“忽略符号链接:$LiteralPath”
}否则{
编写详细的“即将在$($childDir.FullName)上递归…”
试试{#如果.AddRange()由于超出数组列表的容量而失败,我们也必须失败。
$emptySubDirs.AddRange(@(获取递归EmptyDirectories-DoNotValidatePath-LiteralPath$childDir.FullName-Force:$Force))
}抓住{
扔
}
#如果最后添加的条目是当前的子目录,则该子目录。
#根据定义,它本身是空的。
if($emptySubDirs[-1]-eq$childDir.FullName){++$emptyChildDirCount}
}
}#foreach($childDir)。。。
}#如果($childDirs=…)
if(-not$haveFiles-和$emptyChildDirCount-eq$childDirs.Count){
#没有子文件,所有子目录(如果有)都是自己的
#空,因此我们只输出手边的输入路径,作为最高值
#此子树中为空的目录(为空的子代保存)。
$LiteralPath
}否则{
#此目录本身不是空的,因此输出(最高级别)
#空的子代。
$emptySubDirs
}
}

有关代码的提示:

  • PSv3+中提供了
    Get-ChildItem-Directory
    ,它不仅比
    Get-ChildItem |…更短,而且效率更高,其中{$.PSisContainer-eq$True}

  • 使用
    写入主机
    而不是
    [控制台]::WriteLine

  • [System.Convert]::ToBoolean($answer)
    仅适用于区域性不变字符串文本
    'True'
    'False'
    [bool]::TrueString
    [bool]::False string
    ,尽管允许大小写变化和前后空格)


更有效的方法是手动遍历目录树,例如。