计算每个子文件夹中的文件数,忽略具有特定名称的文件
Count number of files in each subfolder, ignoring files with certain name
考虑以下目录树
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
结构总是这样,所以没有更深的子文件夹。我正在编写一个脚本来计算文件的数量:
- 每个 BARXXX 文件夹
- 每个 BARXXX_Y 文件夹
- 名称中带有 "ignore_this" 的文本文件,应在计数中忽略
对于上面的示例,这将导致:
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
似乎是空的。请告诉我哪里做错了。
好吧,首先,您是 运行 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
}
}
我喜欢这种创建对象的方式 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)。
然后我们可以将它的输出直接传递到下一个循环,而不用先存储它。
然后我们可以用供应商 -Exclude
替换另一个 Where-Object
。
最后,我们可以删除 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
大家好!
考虑以下目录树
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
结构总是这样,所以没有更深的子文件夹。我正在编写一个脚本来计算文件的数量:
- 每个 BARXXX 文件夹
- 每个 BARXXX_Y 文件夹
- 名称中带有 "ignore_this" 的文本文件,应在计数中忽略
对于上面的示例,这将导致:
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
似乎是空的。请告诉我哪里做错了。
好吧,首先,您是 运行 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
}
}
我喜欢这种创建对象的方式 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)。
然后我们可以将它的输出直接传递到下一个循环,而不用先存储它。
然后我们可以用供应商 -Exclude
替换另一个 Where-Object
。
最后,我们可以删除 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
大家好!