我发现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 文章:
https://blogs.msdn.microsoft.com/kathykam/2006/03/29/net-format-string-101/
https://blogs.msdn.microsoft.com/kathykam/2006/09/29/net-format-string-102-datetime-format-string/
有关字符串格式的更多详细信息。
答案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
。