考虑以下目录树
ROOT
BAR001
foo_1.txt
foo_2.txt
foo_ignore_this_1.txt
BAR001_a
foo_3.txt
foo_4.txt
foo_ignore_this_2.txt
foo_ignore_this_3.txt
BAR001_b
foo_5.txt
foo_ignore_this_4.txt
BAR002
baz_1.txt
baz_ignore_this_1.txt
BAR002_a
baz_2.txt
baz_ignore_this_2.txt
BAR002_b
baz_3.txt
baz_4.txt
baz_5.txt
baz_ignore_this_3.txt
BAR002_c
baz_ignore_this_4.txt
BAR003
lor_1.txt
结构总是这样,所以没有更深层的子文件夹。我正在编写一个脚本来计算文件数量:
对于上面的示例,这将导致:
Folder Filecount
---------------------
BAR001 2
BAR001_a 2
BAR001_b 1
BAR002 1
BAR002_a 1
BAR002_b 3
BAR002_c 0
BAR003 1
我现在有:
Function Filecount {
param(
[string]$dir
)
$childs = Get-ChildItem $dir | where {$_.Attributes -eq 'Directory'}
Foreach ($childs in $child) {
Write-Host (Get-ChildItem $dir | Measure-Object).Count;
}
}
Filecount -dir "C:\ROOT"
(尚未准备好但正在建设)然而,这不起作用。 $child
似乎是空的。请告诉我我做错了什么。
答案 0 :(得分:1)
嗯,首先,您正在运行ForEach ($childs in $child)
,这种语法是向后的,所以这会导致一些问题!如果你换掉它,那么你就跑了:
ForEach ($child in $childs)
您将获得以下输出:
>2
>2
>1
>1
>1
>3
>0
好的,我现在回复完成的答案。首先,我没有使用Write-Out,而是使用PowerShell自定义对象让PowerShell为我做了艰苦的工作。我将FolderName设置为等于$ child.BaseName,然后在$ Child.FullName上运行GCI以获取文件计数。我添加了一个名为$ ignoreme的额外参数,该参数应该为要忽略的值设置星号值。
现在这里是完整的答案。请记住,我的文件结构与您的文件结构略有不同,因此我的文件数量也在底部不同。
Function Filecount {
param(
[string]$dir="C:\TEMP\Example",
[string]$ignoreme = "*_*"
)
$childs = Get-ChildItem $dir | where {$_.Attributes -eq 'Directory'}
Foreach ($child in $childs) {
[pscustomobject]@{FolderName=$child.Name;ItemCount=(Get-ChildItem $child.FullName | ? Name -notlike $ignoreme | Measure-Object).Count}
}
}
>Filecount | ft -AutoSize
>FolderName ItemCount
>---------- ---------
>BAR001 2
>BAR001_A 1
>BAR001_b 2
>BAR001_C 0
>BAR002 0
>BAR003 0
如果您正在使用PowerShell v 2.0,请改用此方法。
Function Filecount {
param(
[string]$dir="C:\TEMP\Example",
[string]$ignoreme = "*_*"
)
$childs = Get-ChildItem $dir | where {$_.Attributes -eq 'Directory'}
Foreach ($child in $childs) {
$ObjectProperties = @{
FolderName=$child.Name
ItemCount=(Get-ChildItem $child.FullName | ? Name -notlike $ignoreme | Measure-Object).Count}
New-Object PSObject -Property $ObjectProperties
}
}
答案 1 :(得分:1)
我喜欢这种创建对象的方式1RedOne,之前没有看到过,谢谢。
我们可以通过几种方式提高代码的性能。通过使用Filter Left原则,该原则声明任何cmdlet的提供程序本身比通过PowerShell运行更高效,通过执行更少的循环并删除不必要的步骤:
Function Filecount
{
param
(
[string]$dir = ".",
[parameter(mandatory=$true)]
[string]$ignoreme
)
Get-ChildItem -Recurse -Directory -Path $dir | ForEach-Object `
{
[pscustomobject]@{FolderName=$_.Name;ItemCount=(Get-ChildItem -Recurse -Exclude "*$ignoreme*" -Path $_.FullName).count}
}
}
所以,首先我们可以在顶级目录中使用Get-Childitem的-Directory开关(我知道这在v3.0及更高版本中可用,不确定v2.0)。
然后我们可以直接将它的输出传递到下一个循环,而不先存储它。
然后我们可以使用提供商Where-Object
替换另一个-Exclude
。
最后,我们可以删除Measure-Object
作为数组的简单计数:
Filecount "ROOT" "ignore_this" | ft -a
FolderName ItemCount
---------- ---------
BAR001 2
BAR001_a 2
BAR001_b 1
BAR002 1
BAR002_a 1
BAR002_b 3
BAR002_c 0
BAR003 1
干杯人!