首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Windows/Powershell命令在一行中列出每个文件夹的大小、文件数和文件夹数,直到给定的深度

Windows/Powershell命令在一行中列出每个文件夹的大小、文件数和文件夹数,直到给定的深度
EN

Stack Overflow用户
提问于 2015-05-03 11:33:42
回答 2查看 1.4K关注 0票数 1

我正在寻找一个Windows/Powershell命令,该命令在一行中列出每个文件夹的大小、文件数和文件夹数(类似于右键单击资源管理器中的文件夹并查询属性时得到的文件夹)。它将在树中的子文件夹上工作到给定的深度。例如,如果一个人想使用C:\root,直到深度2,输出将类似于

代码语言:javascript
运行
复制
C:\root\dir1  32.6MB  153 files  26 folders
.C:\root\dir1\tan  12.0MB  37 files  12 folders
.C:\root\dir1\win  3.5MB  15 files  2 folders
C:\root\dir2  134.5KB  13 files  0 folders
...

这与Unix du类似。输出将类似于tree的输出,但添加每个项的请求总数。

如何才能做到这一点?

我发现Get Folder Size from Windows Command Line获得了总大小,但没有恢复到选定的深度。此外,本机cmd中的解决方案并不可靠,似乎需要powershell。

注:来自Sysinternals套房的DU是可靠的。我们可以编写一个函数,使用它的输出并递归子树,但是它会在每个请求的深度级别上查询每个分支,因此它可能效率很低。为了第一次机会,我会试试的。我目前正在做这方面的工作,并欢迎对此进行详细阐述。最理想的是有效的解决办法。

Set Recursive-Depth for dir command in dos递归文件夹,但只显示文件夹名。而且它是在本机Windows中,因此不可能可靠地提取总大小(请参阅上面的说明)。

EN

回答 2

Stack Overflow用户

发布于 2015-05-04 19:01:54

我还没有学习powershell,但我确实解决了JScript的问题。

如果您只需要文件夹的总大小(包括所有子文件夹的大小,递归),这将非常简单,因为FileSystemObject folder.size属性直接给出了这个值。但是没有获得相应文件和文件夹计数的属性,因此必须编写自己的递归代码才能获得计数。

folderSummary.js

代码语言:javascript
运行
复制
var fso = new ActiveXObject("Scripting.FileSystemObject");
var maxDepth = parseInt(WScript.Arguments.Item(1));
var files;

procFolder( fso.GetFolder( WScript.Arguments.Item(0) ), 0, new Summary() );

function procFolder( folder, depth, parent ) {
  var summary = new Summary();
  for (files = new Enumerator(folder.Files); !files.atEnd(); files.moveNext()) {
    summary.fileCnt++;
    summary.size += files.item().size;
  }
  for (var folders = new Enumerator(folder.SubFolders); !folders.atEnd(); folders.moveNext()) {
    summary.folderCnt++;
    procFolder( folders.item(), depth+1, summary );
  }  
  if (depth<=maxDepth) WScript.Echo( lpad( summary.folderCnt, '         ' ) + ' folders ' +
                                     lpad( summary.fileCnt,   '         ' ) + ' files '   +
                                     lpad( summary.size, '               ') + ' bytes   ' +
                                     folder.Path
                                   );
  parent.size      += summary.size;
  parent.fileCnt   += summary.fileCnt;
  parent.folderCnt += summary.folderCnt;
}                 

function Summary() {
  this.size = 0;
  this.fileCnt = 0;
  this.folderCnt = 0;
}

function lpad( val, pad ) {
  if (!pad) pad='';
  var rtn=val.toString();
  return (rtn.length<pad.length) ? (pad+rtn).slice(-pad.length) : val;
}

用法-它期望根文件夹作为第一个参数,显示递归深度作为第二个参数。下面是当前目录的一个示例,3层深度:

代码语言:javascript
运行
复制
cscript //nologo folderSummary.js . 3

将JScript打包到混合批处理脚本中非常简单,这样可以更容易地从命令行调用。下面的脚本将根默认为当前文件夹,深度为0。

folderSummary.bat

代码语言:javascript
运行
复制
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
:: folderSummary.bat  [rootPath]  [recursionDepth]
::
::   default rootPath is current folder
::   default recursionDepth is 0
::

::************* Batch portion **********

@echo off
setlocal disableDelayedExpansion
set "root=%~1"
if "%root%" equ "" set "root=."
set "depth=%~2"
if "%depth%" equ "" set "depth=0"
cscript //nologo //E:JScript "%~f0" "%root%" "%depth%"
exit /b


************* JScript portion **********/

var fso = new ActiveXObject("Scripting.FileSystemObject");
var maxDepth = parseInt(WScript.Arguments.Item(1));
var files;

procFolder( fso.GetFolder( WScript.Arguments.Item(0) ), 0, new Summary() );

function procFolder( folder, depth, parent ) {
  var summary = new Summary();
  for (files = new Enumerator(folder.Files); !files.atEnd(); files.moveNext()) {
    summary.fileCnt++;
    summary.size += files.item().size;
  }
  for (var folders = new Enumerator(folder.SubFolders); !folders.atEnd(); folders.moveNext()) {
    summary.folderCnt++;
    procFolder( folders.item(), depth+1, summary );
  }  
  if (depth<=maxDepth) WScript.Echo( lpad( summary.folderCnt, '         ' ) + ' folders ' +
                                     lpad( summary.fileCnt,   '         ' ) + ' files '   +
                                     lpad( summary.size, '               ') + ' bytes   ' +
                                     folder.Path
                                   );
  parent.size      += summary.size;
  parent.fileCnt   += summary.fileCnt;
  parent.folderCnt += summary.folderCnt;
}                 

function Summary() {
  this.size = 0;
  this.fileCnt = 0;
  this.folderCnt = 0;
}

function lpad( val, pad ) {
  if (!pad) pad='';
  var rtn=val.toString();
  return (rtn.length<pad.length) ? (pad+rtn).slice(-pad.length) : val;
}

样本使用情况:

代码语言:javascript
运行
复制
rem root = Current folder, depth = 0
folderSummary

rem root = c:\test, depth = 3
folderSummary c:\test 3

由于它们递归地迭代根路径中的每个文件和文件夹,所以上面的操作可能会比较慢。下面是一个只迭代文件夹的大得多的更快的版本--总大小是从folder.Size获得的,文件/文件夹集合项计数是从Count属性获得的。但是,如果运行在您无法访问的文件/文件夹中,则此快速版本将失败。

fastFolderSummary.bat

代码语言:javascript
运行
复制
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
:: fastFolderSummary.bat  [rootPath]  [recursionDepth]
::
::   default rootPath is current folder
::   default recursionDepth is 0
::

::************* Batch portion **********

@echo off
setlocal disableDelayedExpansion
set "root=%~1"
if "%root%" equ "" set "root=."
set "depth=%~2"
if "%depth%" equ "" set "depth=0"
cscript //nologo //E:JScript "%~f0" "%root%" "%depth%"
exit /b


************* JScript portion **********/

var fso = new ActiveXObject("Scripting.FileSystemObject");
var maxDepth = parseInt(WScript.Arguments.Item(1));

procFolder( fso.GetFolder( WScript.Arguments.Item(0) ), 0, new Summary() );

function procFolder( folder, depth, parent ) {
  var summary = new Summary();
  summary.fileCnt += folder.Files.Count;
  summary.folderCnt += folder.SubFolders.Count;
  for (var folders = new Enumerator(folder.SubFolders); !folders.atEnd(); folders.moveNext()) {
    procFolder( folders.item(), depth+1, summary );
  }  
  if (depth<=maxDepth) WScript.Echo( lpad( summary.folderCnt, '         ' ) + ' folders ' +
                                     lpad( summary.fileCnt,   '         ' ) + ' files '   +
                                     lpad( folder.size, '               ' ) + ' bytes   ' +
                                     folder.Path
                                   );
  parent.fileCnt   += summary.fileCnt;
  parent.folderCnt += summary.folderCnt;
}                 

function Summary() {
  this.fileCnt = 0;
  this.folderCnt = 0;
}

function lpad( val, pad ) {
  if (!pad) pad='';
  var rtn=val.toString();
  return (rtn.length<pad.length) ? (pad+rtn).slice(-pad.length) : val;
}
票数 1
EN

Stack Overflow用户

发布于 2015-05-03 14:56:32

你可以试试这样的东西吗?它不是很有效,我只计算了大小,但是它很容易扩展。

代码语言:javascript
运行
复制
function Measure-DirectorySize([string] $directory, [int] $depth)
{
    if ($depth -lt 0) { return 0; }
    $files = get-childitem $directory -file -force -ea silentlycontinue | 
                measure-object -Property Length -Sum;
    $dirs = get-childitem $directory -Directory -ea silentlycontinue -force |
                % { Measure-DirectorySize ($_.FullName) ($depth - 1) } |
                measure-object -sum;
    return $files.Sum + $dirs.Sum;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30013347

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档