我很确定我做对了,但是想要仔细检查社区。
我有一个文件夹结构,从c:\test\
开始,它有很多文件和文件夹。我在此结构中也有一个文件夹,例如c:\test\something\another\temp\
此文件夹及其子文件夹约占c:\test\
中所有文件的50%或更多。
我希望得到*.txt
及其子文件夹中所有c:\test\
个文件的列表,不包括c:\test\something\another\temp\
及更深层的文件。
我不想枚举包括c:\test\something\another\temp\
在内的所有内容,然后通过管道输出和过滤性能原因:没有必要遍历整个c:\test\something\another\temp\
树,因为没有任何内容那里的兴趣。
它看起来不像Get-ChildItem
cmdlet可以帮助我,我不得不求助于.NET调用并自己编写递归来排除我不需要的文件夹。
Get-ChildItem
具有-Exclude
参数,但它不适用于文件夹,仅适用于文件。
我很好调用.NET库我只是想确保我没有遗漏任何东西而且没有<更简单>使用stock powershell cmdlet执行此操作的方法。
有吗?
答案 0 :(得分:3)
如果目录非常大,
(cmd /c dir c:\test\*.txt /b /s) -notlike 'c:\test\something\another\temp\*'
应该比get-childitem给你更快的结果。
编辑:
这是一个不搜索排除目录的不同版本:
$files =
(cmd /c dir c:\test /b /s /ad) -notlike 'c:\test\something\another\temp*' |
foreach { iex "cmd /c dir $_\*.txt /b /s /a-d" }
不知道如何更快地获得它。
答案 1 :(得分:1)
或者你可以这样做:
Get-ChildItem C:\test -r *.txt | Where {$_.FullName -notlike 'c:\test\something\another\temp\*'}
答案 2 :(得分:0)
您可以通过创建自己的函数来执行此操作,该函数以递归方式调用自身,跳过您不想查看的目录。我认为它正在做你想象的事情,但只是使用内置的cmdlet而不是诉诸于.NET Framework方法。
$searchroot = 'c:\test';
function Get-FilesInDir {
param (
$DirToSearch
)
$ItemsInDir = Get-ChildItem -path $DirToSearch;
foreach ($item in $ItemsInDir) {
if ($item.FullName -eq 'c:\test\something\another\temp') {
continue;
}
if ($item.PSIsContainer) {
Get-FilesInDir $item.FullName;
}
$item.FullName;
}
}
Get-FilesInDir $searchroot
这将输出找到的每个文件的完整路径。
如果您有要排除的目录列表,可以将它们放入数组并修改if
周围的continue
测试以检查每个路径以查看它是否在该数组中。
答案 3 :(得分:0)
利用管道的另一个选择:
function Get-FilesInDir {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline=$true)]
$Path,
$Exclude
)
Process {
$Path | ForEach-Object {
if( (Resolve-path $_).Path.StartsWith($Exclude) ) { return }
Get-ChildItem -Path:$_ |
ForEach-Object {
if($_.PSIsContainer) { Get-FilesInDir -Path:$_.FullName -Exclude:$Exclude }
$_.FullName
}
}
}
}