在默认的 PowerShell ls 命令中显示人类可读的文件大小

Tom*_*eld 37 powershell powershell-2.0

如何修改PowerShell 中的默认值ls( Get-ChildItem) 以显示人类可读的文件大小,就像ls -h在 *nix 机器上一样?

ls -lh 对文件大小进行简单的逻辑处理,以便它显示非常小的文件的字节数,超过 1K 的文件显示千字节(如果小于 10K,则显示一位小数),以及显示超过 1M 的文件兆字节(如果小于 10MB,显示一位小数) .

Ind*_*rek 17

首先,创建以下函数:

Function Format-FileSize() {
    Param ([int]$size)
    If     ($size -gt 1TB) {[string]::Format("{0:0.00} TB", $size / 1TB)}
    ElseIf ($size -gt 1GB) {[string]::Format("{0:0.00} GB", $size / 1GB)}
    ElseIf ($size -gt 1MB) {[string]::Format("{0:0.00} MB", $size / 1MB)}
    ElseIf ($size -gt 1KB) {[string]::Format("{0:0.00} kB", $size / 1KB)}
    ElseIf ($size -gt 0)   {[string]::Format("{0:0.00} B", $size)}
    Else                   {""}
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以管的输出Get-ChildItem通过Select-Object,并使用计算的属性设置格式的文件大小:

Get-ChildItem | Select-Object Name, @{Name="Size";Expression={Format-FileSize($_.Length)}}
Run Code Online (Sandbox Code Playgroud)

当然可以改进该函数以考虑 PB 范围内的大小以及更多,或者根据需要改变小数点的数量。

  • 对我来说,这个函数不能处理大于 ~2GB 的文件,因为 `$size` 被定义为一个 `int`,即 [a `int32`](https://devblogs.microsoft.com/scripting/understanding -powershell中的数字/)。为了处理大文件,将 `$size` 定义为 `int64` 或 `uint64`。 (2认同)

wal*_*umi 16

尝试这个

PS> gc c:\scripts\type\shrf.ps1xml

<Types>
<Type>
  <Name>System.IO.FileInfo</Name>
   <Members>
      <ScriptProperty>
          <Name>FileSize</Name>
          <GetScriptBlock>
             switch($this.length) {
               { $_ -gt 1tb } 
                      { "{0:n2} TB" -f ($_ / 1tb) }
               { $_ -gt 1gb } 
                      { "{0:n2} GB" -f ($_ / 1gb) }
               { $_ -gt 1mb } 
                      { "{0:n2} MB " -f ($_ / 1mb) }
               { $_ -gt 1kb } 
                      { "{0:n2} KB " -f ($_ / 1Kb) }
               default  
                      { "{0} B " -f $_} 
             }      
          </GetScriptBlock>
     </ScriptProperty>   
  </Members>
</Type>
</Types>

PS> Update-TypeData -AppendPath c:\scripts\type\shrf.ps1xml -verbose
PS> get-childItem $env:windir  | select Name,FileSize,length
PS> # you can paste this in your profile
PS> 
Run Code Online (Sandbox Code Playgroud)

您还可以在 PS3 中使用动态类型数据:

   PS> Update-TypeData -TypeName System.IO.FileInfo -MemberName FileSize -MemberType ScriptProperty -Value { 

    switch($this.length) {
               { $_ -gt 1tb } 
                      { "{0:n2} TB" -f ($_ / 1tb) }
               { $_ -gt 1gb } 
                      { "{0:n2} GB" -f ($_ / 1gb) }
               { $_ -gt 1mb } 
                      { "{0:n2} MB " -f ($_ / 1mb) }
               { $_ -gt 1kb } 
                      { "{0:n2} KB " -f ($_ / 1Kb) }
               default  
                      { "{0} B " -f $_} 
             }      

 } -DefaultDisplayPropertySet Mode,LastWriteTime,FileSize,Name
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案!很难相信没有“Get-ChildItem”的开关可以开箱即用 (4认同)
  • 当简单的事情(例如列出具有人类可读大小的文件)需要编写自己的脚本时,怎么会有人认真对待 powershell。 (3认同)
  • 很好的答案,但我再次发现,你必须编写多少 Powershell 代码才能完成像“-h”这样简单的事情,这很搞笑 (3认同)

Not*_*1ds 16

这是对这个相当古老的问题的一些正交答案。这不是对字面上提出的问题的答案,而是更多关于问题的“精神”。即使在问题提出多年后,这也不是一个可能的答案。但现在,它可能对某些来寻找此信息的人有用(就像我今天所做的那样)。

ls -lh由于最初的问题指出这在 *nix 中是多么容易,我意识到安装了 WSL(Linux 的 Windows 子系统)后,从 PowerShell 中使用 Linux 是理所当然的:

PS> wsl ls -lh
Run Code Online (Sandbox Code Playgroud)

...在 PowerShell 中为我提供当前目录上我想要的结果(听起来像 OP 所做的)。更好的是,如果您已exa安装在 WSL 实例中,wsl exa -l则更加漂亮(默认为-h)。

请注意,如果您想要不同的目录,则使用该命令时需要一些“技巧” wsl。由于在 WSL 实例内运行的实用程序(例如ls)仅了解 Linux 路径,因此您不能执行以下操作:

PS> wsl ls -lh C:\
Run Code Online (Sandbox Code Playgroud)

相反,有两种选择。首先,您可以使用 Windows 路径的 WSL 等效项。例如:

PS> wsl ls -lh /mnt/c
PS> wsl exa -l /mnt/c
Run Code Online (Sandbox Code Playgroud)

或者,只需使用选项设置 WSL 实例的目录--cd,如下所示:

PS> wsl --cd C:\ ls -lh # or
PS> wsl --cd C:\ exa -l
Run Code Online (Sandbox Code Playgroud)

这也适用于相对目录路径:

PS> wsl --cd .. ls -lh # or
PS> wsl --cd .. exa -l
Run Code Online (Sandbox Code Playgroud)

不用担心(如果您担心的话)——它不会更改 PowerShell 中的当前目录。当 WSL 实例在运行ls命令后退出时,PowerShell 将保留其当前环境;就像运行子 shell 一样(在 PowerShell 或 Bash 等 Linux shell 中)。

PowerShell 和 WSL 各自都很棒,但将两者结合在一起会给您带来更强大的功能。

PS 这适用于 WSL1 或 WSL2,但如果您要在 WSL 中处理大量 Windows 文件,版本 1(目前)速度要快一个数量级。使用虚拟化 ext4 文件系统时,WSL2 速度更快。

  • 哇,我不知道你可以在 PowerShell 中运行 WSL。不再有冗长的 PS BS。谢谢你! (5认同)
  • 偷偷摸摸的,我喜欢。如果您是第一次启动“wsl”,则第一个函数调用会有点缓慢,但后续调用是瞬时的。 (2认同)

jmr*_*cha 13

类似于以下仅列出文件大小的内容。是的,它的眼睛有点痛,但它设法完成了工作。

要转换为 KB:

ls | Select-Object Name, @{Name="KiloBytes";Expression={$_.Length / 1KB}}
Run Code Online (Sandbox Code Playgroud)

要转换为 MB:

ls | Select-Object Name, @{Name="MegaBytes";Expression={$_.Length / 1MB}}
Run Code Online (Sandbox Code Playgroud)


ego*_*lus 6

根据 walid toumi 的回答:

操作步骤:

  • 使用新的FileSize-Property创建您自己的类型文件
  • 更改 FileInfo 的标准输出格式
  • 加载更改 $PROFILE

使用新的FileSize-Property创建您自己的类型文件

  • 创建你自己的类型文件:(MyTypes.ps1xml
    我把它放在$Env:USERPROFILE\Documents\WindowsPowershell,所以就在我的旁边$PROFILE

    <?xml version="1.0" encoding="utf-8" ?>
    <Types>
        <Type>
            <Name>System.IO.FileInfo</Name>
            <Members>
                <ScriptProperty>
                    <!-- Filesize converts the length to a human readable
                        format (kb, mb, gb, tb) -->
                    <Name>FileSize</Name>
                    <GetScriptBlock>
                        switch($this.length) {
                            { $_ -gt 1tb } 
                                { "{0:n2} TB" -f ($_ / 1tb) ; break }
                            { $_ -gt 1gb } 
                                { "{0:n2} GB" -f ($_ / 1gb) ; break }
                            { $_ -gt 1mb } 
                                { "{0:n2} MB " -f ($_ / 1mb) ; break }
                            { $_ -gt 1kb } 
                                { "{0:n2} KB " -f ($_ / 1Kb) ; break }
                            default
                                { "{0}  B " -f $_}
                        }
                    </GetScriptBlock>
                </ScriptProperty>
            </Members>
        </Type>
    </Types>
    
    Run Code Online (Sandbox Code Playgroud)
  • 在 powershell 会话中加载新属性:

    • Update-TypeData -PrependPath $Env:USERPROFILE\Documents\WindowsPowershell\MyTypes.ps1xml
  • 试试新房源
    • Get-ChildItem | Format-Table -Property Name, Length, FileSize

更改 FileInfo 的标准输出格式

  • 创建您自己的文件格式文件:(MyFileFormat.format.ps1xml 再次在$Env:USERPROFILE\Documents\WindowsPowershell\

    <?xml version="1.0" encoding="utf-8" ?> 
    <Configuration>
        <SelectionSets>
            <SelectionSet>
                <Name>FileSystemTypes</Name>
                <Types>
                    <TypeName>System.IO.DirectoryInfo</TypeName>
                    <TypeName>System.IO.FileInfo</TypeName>
                </Types>
            </SelectionSet>
        </SelectionSets>
    
        <!-- ################ GLOBAL CONTROL DEFINITIONS ################ -->
        <Controls>
            <Control>
                <Name>FileSystemTypes-GroupingFormat</Name>
                        <CustomControl>
                            <CustomEntries>
                                <CustomEntry>
                                    <CustomItem>
                                        <Frame>
                                            <LeftIndent>4</LeftIndent>
                                            <CustomItem>
                                                <Text AssemblyName="System.Management.Automation" BaseName="FileSystemProviderStrings" ResourceId="DirectoryDisplayGrouping"/>
                                                <ExpressionBinding>
                                                  <ScriptBlock>
                                                      $_.PSParentPath.Replace("Microsoft.PowerShell.Core\FileSystem::", "")                                                  
                                                  </ScriptBlock>
                                                </ExpressionBinding>
                                                <NewLine/>
                                            </CustomItem> 
                                        </Frame>
                                    </CustomItem>
                                </CustomEntry>
                            </CustomEntries>
                </CustomControl>
            </Control>
        </Controls>
    
        <!-- ################ VIEW DEFINITIONS ################ -->
    
        <ViewDefinitions>
           <View>
                <Name>children</Name>
                <ViewSelectedBy>
                    <SelectionSetName>FileSystemTypes</SelectionSetName>
                </ViewSelectedBy>
                <GroupBy>
                    <PropertyName>PSParentPath</PropertyName> 
                    <CustomControlName>FileSystemTypes-GroupingFormat</CustomControlName>  
                </GroupBy>
                <TableControl>
                    <TableHeaders>
                       <TableColumnHeader>
                          <Label>Mode</Label>
                          <Width>7</Width>
                          <Alignment>left</Alignment>
                       </TableColumnHeader>
                        <TableColumnHeader>
                            <Label>LastWriteTime</Label>
                            <Width>25</Width>
                            <Alignment>right</Alignment>
                        </TableColumnHeader>
                        <TableColumnHeader>
                            <Label>FileSize</Label>
                            <Width>14</Width>
                            <Alignment>right</Alignment>
                        </TableColumnHeader>
                        <TableColumnHeader/>
                    </TableHeaders>
                    <TableRowEntries>
                        <TableRowEntry>
                            <Wrap/>
                            <TableColumnItems>
                                <TableColumnItem>
                                    <PropertyName>Mode</PropertyName>
                                </TableColumnItem>
                                <TableColumnItem>
                                    <ScriptBlock>
                                        [String]::Format("{0,10}  {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t"))
                                    </ScriptBlock>
                                </TableColumnItem>
                                <TableColumnItem>
                                <PropertyName>FileSize</PropertyName>
                                </TableColumnItem>
                                <TableColumnItem>
                                    <PropertyName>Name</PropertyName>
                                </TableColumnItem>
                            </TableColumnItems>
                        </TableRowEntry>
                    </TableRowEntries>
                </TableControl>
            </View>
            <View>
                <Name>children</Name>
                <ViewSelectedBy>
                    <SelectionSetName>FileSystemTypes</SelectionSetName>
                </ViewSelectedBy>
                <GroupBy>
                    <PropertyName>PSParentPath</PropertyName> 
                    <CustomControlName>FileSystemTypes-GroupingFormat</CustomControlName>  
                </GroupBy>
                <ListControl>
                    <ListEntries>
                        <ListEntry>
                            <EntrySelectedBy>
                                <TypeName>System.IO.FileInfo</TypeName>
                            </EntrySelectedBy>
                            <ListItems>
                                <ListItem>
                                    <PropertyName>Name</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>FileSize</PropertyName>
                                </ListItem>
                               <ListItem>
                                    <PropertyName>CreationTime</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>LastWriteTime</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>LastAccessTime</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>Mode</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>LinkType</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>Target</PropertyName>
                                </ListItem>                        
                                <ListItem>
                                    <PropertyName>VersionInfo</PropertyName>
                                </ListItem>
                            </ListItems>
                        </ListEntry>
                        <ListEntry>
                            <ListItems>
                                <ListItem>
                                    <PropertyName>Name</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>CreationTime</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>LastWriteTime</PropertyName>
                                </ListItem>
                                <ListItem>
                                    <PropertyName>LastAccessTime</PropertyName>
                                </ListItem>
                              <ListItem>
                                <PropertyName>Mode</PropertyName>
                              </ListItem>
                              <ListItem>
                                <PropertyName>LinkType</PropertyName>
                              </ListItem>
                              <ListItem>
                                <PropertyName>Target</PropertyName>
                              </ListItem>
                            </ListItems>
                        </ListEntry>
                    </ListEntries>
                </ListControl>
            </View>
            <View>
                <Name>children</Name>
                <ViewSelectedBy>
                    <SelectionSetName>FileSystemTypes</SelectionSetName>
                </ViewSelectedBy>
                <GroupBy>
                    <PropertyName>PSParentPath</PropertyName> 
                    <CustomControlName>FileSystemTypes-GroupingFormat</CustomControlName>  
                </GroupBy>
                <WideControl>
                    <WideEntries>
                        <WideEntry>
                            <WideItem>
                                <PropertyName>Name</PropertyName>
                            </WideItem>
                        </WideEntry>
                        <WideEntry>
                            <EntrySelectedBy>
                                <TypeName>System.IO.DirectoryInfo</TypeName>
                            </EntrySelectedBy>
                            <WideItem>
                                <PropertyName>Name</PropertyName>
                                <FormatString>[{0}]</FormatString>
                            </WideItem>
                        </WideEntry>
                    </WideEntries>
                </WideControl>
            </View>
            <View>
                <Name>FileSecurityTable</Name>
                <ViewSelectedBy>
                    <TypeName>System.Security.AccessControl.FileSystemSecurity</TypeName>
                </ViewSelectedBy>
                <GroupBy>
                    <PropertyName>PSParentPath</PropertyName> 
                    <CustomControlName>FileSystemTypes-GroupingFormat</CustomControlName>  
                </GroupBy>
                <TableControl>
                    <TableHeaders>
                       <TableColumnHeader>
                          <Label>Path</Label>
                       </TableColumnHeader>
                       <TableColumnHeader />
                       <TableColumnHeader>
                          <Label>Access</Label>
                       </TableColumnHeader>
                    </TableHeaders>
                    <TableRowEntries>
                        <TableRowEntry>
                            <TableColumnItems>
                                <TableColumnItem>
                                    <ScriptBlock>
                                        split-path $_.Path -leaf
                                    </ScriptBlock>
                                </TableColumnItem>
                                <TableColumnItem>
                                <PropertyName>Owner</PropertyName>
                                </TableColumnItem>
                                <TableColumnItem>
                                    <ScriptBlock>
                                        $_.AccessToString
                                    </ScriptBlock>
                                </TableColumnItem>
                            </TableColumnItems>
                        </TableRowEntry>
                    </TableRowEntries>
                </TableControl>
            </View>
           <View>
                <Name>FileSystemStream</Name>
                <ViewSelectedBy>
                    <TypeName>Microsoft.PowerShell.Commands.AlternateStreamData</TypeName>
                </ViewSelectedBy>
                <GroupBy>
                    <PropertyName>Filename</PropertyName> 
                </GroupBy>
                <TableControl>
                    <TableHeaders>
                       <TableColumnHeader>
                          <Width>20</Width>
                          <Alignment>left</Alignment>
                       </TableColumnHeader>
                        <TableColumnHeader>
                            <Width>10</Width>
                            <Alignment>right</Alignment>
                        </TableColumnHeader>
                    </TableHeaders>
                    <TableRowEntries>
                        <TableRowEntry>
                            <TableColumnItems>
                                <TableColumnItem>
                                    <PropertyName>Stream</PropertyName>
                                </TableColumnItem>
                                <TableColumnItem>
                                    <PropertyName>Length</PropertyName>
                                </TableColumnItem>
                            </TableColumnItems>
                        </TableRowEntry>
                    </TableRowEntries>
                </TableControl>
            </View>          
        </ViewDefinitions>
    </Configuration>
    
    Run Code Online (Sandbox Code Playgroud)

    (它的allmost原来直接拷贝$PSHOME\FileFormat.format.ps1xml。我只改LengthFileSize几十倍)

  • 在我们的 powershell 会话中加载新格式:

    • Update-FormatData -PrependPath $Env:USERPROFILE\Documents\WindowsPowershell\MyFileFormat.format.ps1xml
  • 试试新房源
    • Get-ChildItem

加载更改 $PROFILE

  • 将这些行复制到$PROFILE以加载每个新会话中的更改

    # local path to use in this script
    $scriptpath = Split-Path -parent $MyInvocation.MyCommand.Definition
    
    # custom types and formats
    # currently only System.IO.FileInfo is changed
    update-TypeData -PrependPath $scriptpath\MyTypes.ps1xml
    update-FormatData -PrependPath $scriptpath\MyFileFormat.format.ps1xml
    
    Run Code Online (Sandbox Code Playgroud)