Показывать удобочитаемые размеры файлов в стандартной команде PowerShell ls


26

Как я могу изменить default ls( Get-ChildItem) в PowerShell, чтобы он отображал удобочитаемые размеры файлов, как ls -hна компьютере * nix?

ls -lh выполняет простую логику с размером файла, так что он показывает байты для действительно маленьких файлов, килобайты для файлов размером более 1 КБ (с одним десятичным знаком, если он меньше 10 КБ), и мегабайт для файлов размером более 1 МБ (с одним десятичным знаком, если он меньше 10 МБ) ,

Ответы:


10

попробуй это

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> 

вы также можете использовать данные динамического типа с 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

Мне действительно нравится строить его как дополнительную собственность. Единственная проблема с использованием версии PS3 заключается в том, что я получаю: Update-TypeData : Error in TypeData "System.IO.FileInfo": The member DefaultDisplayPropertySet is already present.Запуск последней полной версии PS3 от 9/4.
Том Мэйфилд

3
Отличный ответ! Трудно поверить, что нет переключателя Get-ChildItem, который просто сделал бы это из коробки
Бен Коллинз

Отличный ответ, но кто-нибудь -DefaultDisplayPropertySetдолжен работать?
Ник Кокс

Не работает, как сказал @ ThomasG.Mayfield.
ChrisBrownie55

14

Сначала создайте следующую функцию:

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                   {""}
}

Затем вы можете передать вывод Get-ChildItemчерез Select-Objectи использовать вычисляемое свойство для форматирования размера файла:

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

Эта функция, конечно, может быть улучшена для учета размеров в диапазоне PB и более или для изменения количества десятичных знаков по мере необходимости.


Есть ли причина, по которой псевдоним не может быть создан для этого как самого Gethilditem (проверьте, есть ли флаг -lh или что-то, а если нет, то просто используйте Get-ChildItem, иначе используйте это)
soandos

Вы не можете создавать псевдонимы для команд по конвейеру или переопределять псевдонимы по умолчанию. Если вы можете использовать псевдоним, например ls2, попробуйте создать другую функцию, которая будет выполнять логику, описанную вами, на основе параметра, а затем добавить для него псевдоним. Смотрите здесь для получения дополнительной информации о создании псевдонимов.
Индрек

В качестве альтернативы посмотрите в файлы пользовательского форматирования, чтобы расширить вывод командлета. Смотрите эту тему форума для примера. Кроме того, чтобы функция форматирования сохранялась в сеансах PowerShell, добавьте ее в файл профиля (см. Get-Variable profileЕе расположение).
Индрек

1
Для меня эта функция не работает файлы размером более 2 Гб ~, так как $size определяется как int, который . Чтобы это работало с большими файлами, определите как или . int32$sizeint64uint64
Алекс Лич

Я получаю Select-Object : Es wurde kein Positionsparameter gefunden, der das Argument "System.Collections.Hashtable" akzeptiert.. Как я могу указать путь? Я использую $pst= Get-ChildItem -Path $home_user -Filter *.pst -Recurse -File| Sort-Object Length -Descending | ForEach-Object{ $_.FullName}. Это работает, но без размеров файла.
Тимо

6

Что-то вроде следующего для перечисления только размеров файлов. Да, это немного болит на глазах, но это удается сделать работу.

Для преобразования в КБ:

ls | Select-Object Name, @{Name="KiloBytes";Expression={$_.Length / 1KB}}

Для преобразования в МБ:

ls | Select-Object Name, @{Name="MegaBytes";Expression={$_.Length / 1MB}}

1
Лучший ответ, без сценария / функции. pipeРешение!
Тимо

3

основываясь на ответе Валида Туми:

Шаги, чтобы сделать:

  • Создайте свой собственный Type-файл с новым FileSize-Property
  • Изменить стандартный формат вывода для FileInfo
  • загрузить изменения в $PROFILE

Создайте свой собственный Type-файл с новым FileSize-Property

  • Создайте свой собственный Type-файл: 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>
  • загрузить новое свойство в 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>

    (Это Allmost прямой копией оригинала $PSHOME\FileFormat.format.ps1xml. Я только изменил Lengthв FileSizeнесколько раз)

  • загрузите новый формат в нашем сеансе 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

0

Я использовал решение jmreicha с псевдонимом в моем профиле $:

function Get-ChildItem-MegaBytes {
  ls $args | Select-Object Name, @{Name="MegaBytes";Expression={$_.Length / 1MB}}
}

Set-Alias -name megs -val Get-ChildItem-MegaBytes

Теперь я просто набираю: megs [whatever]

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.