如何解读 Powershell 的文本格式化语法?

如何解读 Powershell 的文本格式化语法?

我发现PowerShell 脚本我认为我可以适应我的目的。

它包含格式化输出的这一行:

$largeSizefiles = get-ChildItem -path $filesLocation -include $Extension -recurse -ErrorAction "SilentlyContinue" | ? { $_.GetType().Name -eq "FileInfo" } | where-Object {$_.Length -gt $fileSize} | sort-Object -property length  | Select-Object Name, @{Name="Size In KB";Expression={ "{0:N0}" -f ($_.Length / 1KB)}},@{Name="LastWriteTime";Expression={$_.LastWriteTime}},@{Name="Path";Expression={$_.directory}} -first $filesLimit

关键部分似乎是这样的:

Select-Object Name, @{Name="Size In KB";Expression={ "{0:N0}" -f ($_.Length / 1KB)}},@{Name="LastWriteTime";Expression={$_.LastWriteTime}},@{Name="Path";Expression={$_.directory}} -first $filesLimit

我已经阅读了 ss64.com 上有关 Select-Object 的教程,但没有找到任何内容来解释 @{.....} 形式的表达式如何格式化文本。

ss64.com@ 运算符页面上显示的格式为 @( ... ),带有括号,而不是大括号。

上述代码产生以下输出:

Name          : RPI-Image-1-Copy.img
Size In MB    : 29,477
Path          : D:\VirtualDriveShare
LastWriteTime : 8/18/2015 6:27:51 PM

我熟悉多种编程语言,但这对我来说并不明显,而且我在网上找不到任何明确的解释。有人能给我推荐一个好的教程吗?

答案1

Select-Object 可以为每个项目使用 Header/Values 的哈希表。在此示例中:

Select-Object Name, @{Name="Size In KB";Expression={ "{0:N0}" -f ($_.Length / 1KB)}} ...

脚本选择名称,然后选择从当前管道对象的长度参数得出的“以 KB 为单位的名称”。

进一步格式化,首先将其除以 1024,然后使用 {0:N0} 来显示它。

Powershell 使用 .Net 字符串格式语法进行显示 - 在这种情况下 {0:N0} 转换为:

// N or n (Number): It represent how many decimal places of zeros to show.
String.Format("{0:N4}", pos);      //”10.0000″

您可能想看看 Kathy Kam 的 Format 101 和 Format 102 文章:

有关字符串格式的更多详细信息。

答案2

您缺少的是@{...}表示由键值对组成的哈希表数组。

正如评论中指出的那样,有一个有关此事的 Technet 文章在您的示例中,发生的情况是将名称/标题分配给哈希表中的键,并将具有格式表达式的变量分配给哈希表中的值。

PowerShell 中的哈希表相当简单,但如果它有用的话,ss64 的页面在这里, 和Technet 有一个教程页面也一样。

答案3

我同意所有其他答案,哈希表在这种情况下是计算属性。我发现这些单行代码很棒,但它们可以以更好的方式呈现。技术上仍然是单行代码,但可读性在不同规模上有所不同。

$largeSizefiles = get-ChildItem `
    -path $filesLocation `
    -include $Extension `
    -recurse `
    -ErrorAction "SilentlyContinue" | 
  Where-object { ($_.GetType().Name -eq "FileInfo") `
            -and ($_.Length -gt $fileSize)} | 
  sort-Object -property length  | 
  Select-Object Name, 
    @{Name="Size In KB";Expression={ "{0:N0}" -f ($_.Length / 1KB)}}, 
    @{Name="LastWriteTime";Expression={$_.LastWriteTime}}, 
    @{Name="Path";Expression={$_.directory}} -first $filesLimit

如果 PoSh 需要继续(在 a,或 a之后|),那么您可以简单地插入换行符,或者当然在行继续符之后插入反引号 ` 。

答案4

@{...=...; ...=...}哈希表。您可能知道它们在其他语言中是“字典”。这些是键/值对。分号 ( ;) 分隔不同的对,键和值由等号 ( =) 分隔。请注意,键可以有隐含的引号,使其成为字符串。

{ "{0:N0}" -f ($_.Length / 1KB) }部件是脚本块。有很多这样的;Expression哈希表中的所有键都映射到一个。您可以通过没有前缀的花括号来判断这一点。这些本质上是匿名函数 (lambda)。是$_来自管道的当前项,因此当执行此脚本块时,它会扩展为来自管道输入的单个项。

特定的脚本块"{0:N0}" -f ($_.Length / 1KB)部分只是使用-f操作员进行格式化。这相当于 .NET 的String.Format,其中模式字符串在左侧,模式的参数是右侧的对象数组。0只是参数索引(因此是第一个参数), 告诉:N0它将其格式化为小数点后 0 位的数字。

现在,在所有哈希表之间,我们都有一堆逗号。它们构成了一个大批!原来周围的@(...)部分是可选的。

因此,我们有一个包含几个字符串的数组和一堆带有键Name和的哈希表Expression,并且该数组是传递给Select-Object。也就是说,它是-Property参数。请注意 SS64 文档中的这一行:

要向对象添加计算属性,请指定哈希表作为参数的值-Property。哈希表必须包含两个键:姓名表达使用 Expression 键分配一个脚本块,该脚本块将确定属性的值。

现在一切都变得有意义了。它只是Select-Object转换输入,并将一堆“计算的”(由脚本块确定的)属性和一个“未计算的”(已存在于传入对象上)属性组合在一起,用于输出对象。

小提示:我认为这个特定的计算属性有点愚蠢:

@{Name="LastWriteTime";Expression={$_.LastWriteTime}}

我看不出有任何理由不能像以前那样直接选择它Name

相关内容