【问题标题】:Formatting a text file with columns in powershell在powershell中格式化带有列的文本文件
【发布时间】:2020-10-28 18:36:05
【问题描述】:

我正在尝试从哈希表创建格式良好的 Txt 文件(必须是 Txt 不能是 CSV)。

这是我创建文本文件的代码

$hashTable.GetEnumerator() | Sort-Object Name |
ForEach-Object {"{0} `t`t: {1} `t`t: {2} `t`t: {3} `t`t: {4}" -f $_.DisplayName,$_.EmployeeNo,$_.Email, $_.SamName,$_.Upn}|
Add-Content $textFilePath

正如您所看到的 - 当有人输入带有长名称的 Txt 文件时,它会弄乱格式,因为选项卡只是移动了。

我正在寻找一种动态设置文本文件中列宽的解决方案。

【问题讨论】:

  • 顺便说一句:我认为这只是一个发布工件,但您的代码不能按原样工作,因为在管道中被视为 $_ 的内容不是 AD 用户对象直接,它是一个System.Collections.DictionaryEntry 实例,其.Value 属性包含AD 用户对象。换句话说,不是$_.DisplayName,而是$_.Value.DisplayName,以此类推。

标签: powershell object output text-files hashtable


【解决方案1】:

使用 PowerShell 的输出格式系统,其 Format-Table cmdlet 生成人类可读的列对齐表示,但请注意,这些通常适合以后编程处理:

($hashTable.GetEnumerator() | Sort-Object Name).Value | 
  Format-Table -AutoSize -Property DisplayName, EmployeeNo, Email, SamName, Upn | 
    Out-File $textFilePath -Encoding Utf8 -Width 1024 
  • $hashTable.GetEnumerator() | Sort-Object Name 将哈希表条目枚举为System.Collections.DictionaryEntry 条目,并按它们的.Name (.Key) 属性对其进行排序。

    • 请注意,.GetEnumerator() 调用对于按其键(名称)对散列表 条目 进行排序是必需的;没有它,散列表作为一个整体将通过管道作为单个对象发送,在这种情况下Sort-Object实际上是一个否- op - 根据定义,如果只有一个对象,则无需排序;比较来自:
      @{ zach = 1; moe = 2; aardvark = 0 } | Sort-Object Name
      的输出 到输出:
      @{ zach = 1; moe = 2; aardvark = 0 }.GetEnumerator() | Sort-Object Name
      在第一个命令中,Sort-Object 调用无效。
  • .Value 然后提取条目的值(这也可以使用... | ForEach-Object Value 以流方式完成)。

  • 这些值似乎是 Active Directory 用户对象,因此您只需将所需属性 names 的列表传递给 Format-Table,它们形成输出表列名称,而相应的属性values 构成列值。

  • 请注意,使用Out-File 而不是Add-Content (Set-Content),因为只有它会自动将Format-Table 输出的格式objects 转换为其预期的字符串表示形式,就像您将在控制台(终端)中查看。

    • -Width 1024 确保不会根据当前控制台窗口的宽度截断表格行;根据需要进行调整。
    • -Encoding Utf8为例,控制输出编码;请注意,Windows PowerShell 默认为“Unicode” (UTF-16LE),而在 PowerShell [Core] v6+ 中默认为无 BOM 的 UTF-8。有关 Windows PowerShell 与 PowerShell [Core] 中默认字符编码的更多信息,请参阅 this answer

【讨论】:

  • Format-Table-Width 参数吗?我想这可能与Out-File 相符。检查文档并在 5.1 和 7.0 中进行测试。我也不确定我们是否需要 .GetEnumerator() ,在这种情况下 $hashTable.Values | Sort-Object Name | ... 似乎也能正常工作。是否有理由指定编码?
  • 是的 - 谢谢@Steven:-Width 属于 Out-File 命令 - 已修复。至于你的其他观点:请看我的更新。
  • 啊,我明白我的错误了。在我的测试数据中,我包含了一个 name 属性。因此,对底层对象的 name 属性进行排序,而不是哈希的键。谢谢!
  • 我明白了。在我的错误实验中,我没有将哈希表全部发送到管道中。我发送了哈希表的.Values 属性。如果存储在散列中的对象具有名称属性,例如 AD 用户,PwSh 会对其进行排序。当然,这与按键排序不同。我的错误在于创建确实具有 name 属性的测试数据,而实际上我不知道密钥是什么。其余的紧随其后。
  • 知道了,@Steven。可能增加混乱的是问题中的代码不能按原样工作,因为它必须是$_.DisplayName,而不是$_.Value.DisplayName,等等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-05
  • 2012-04-17
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
相关资源
最近更新 更多