PowerShell格式文本文件

时间:2016-01-20 12:52:23

标签: powershell

我从PowerShell查询中获得以下输出。我没有访问服务器来运行查询,所以我没有选择影响输出格式。

示例:

String dateFmt = cell.getCellStyle().getDataFormatString();

if (DateUtil.isCellDateFormatted(cell)) {
    double val = cell.getNumericCellValue();
    Date date = DateUtil.getJavaDate(val);

    String dateFmt = cell.getCellStyle().getDataFormatString();

    System.out.println("dateFmt "+dateFmt);

    value = new CellDateFormatter(dateFmt).format(date);

    System.out.println("Date "+value);

}

如何格式化上面的内容以获得更多可用的内容,可能就像表格格式一样:

Name          : folderC
FullName      : D:\folderA\folderB\folderC
Length        :
CreationTime  : 2/8/2014 11:12:58 AM
LastAccessTime: 2/8/2014 11:12:58 AM

Name          : filename.txt
FullName      : D:\folderA\folderB\filename.txt
Length        : 71560192
CreationTime  : 11/25/2015 3:10:43 PM
LastAccessTime: 11/25/2015 3:10:43 PM

2 个答案:

答案 0 :(得分:4)

我认为您需要将文本拆分为记录,用等号替换冒号,以便您可以使用ConvertFrom-StringData将每条记录转换为哈希值,然后您可以将其输入New-Object以转换为对象。然后可以使用ConvertTo-Csv将对象输出到管道分离的数据中。像这样:

$x = @"
Name           : folderC
FullName       : D:\folderA\folderB\folderC
Length         : 0
CreationTime   : 2/8/2014 11:12:58 AM
LastAccessTime : 2/8/2014 11:12:58 AM

Name           : filename.txt
FullName       : D:\folderA\folderB\filename.txt
Length         : 71560192
CreationTime   : 11/25/2015 3:10:43 PM
LastAccessTime : 11/25/2015 3:10:43 PM
"@

($x -split '[\r\n]+(?=Name)') | % {
  $_ -replace '\s+:\s+', '='
} | % {
  $_ | ConvertFrom-StringData
} | % {
  New-Object psobject -Property $_
}  | ConvertTo-Csv -Delimiter '|' -NoTypeInformation

答案 1 :(得分:3)

正如@alroc在对该问题的评论中指出的那样,OP可能对象可用,因为它们声明输出是“来自Powershell查询” - 如果是这样,使用通常的cmdlet简单地重新格式化对象数组是一种选择 相比之下,这个答案假设只有问题中印刷的文本表示可用。

Dave Sexton's answer是一个更简单,更优雅的选择,如果:

  • 输入没有值(OP的示例输入有)。
  • 输入文件足够小,可以作为一个整体读入内存。

如果您想要更好地控制输入转换为自定义对象的方式,请考虑以下方法避免上述问题和/或,尤其是在创建属性方面使用[string]以外的类型:扩展下面的toObj()函数(如所写,所有属性也只是字符串)。

Get-Content File | % `
  -begin {
    function toObj([string[]] $lines) {
      $keysAndValues = $lines -split '(?<=^[^ :]+)\s*: '
      $htProps = @{}
      for ($i = 0; $i -lt $keysAndValues.Count; $i += 2) {
        $htProps.($keysAndValues[$i]) = $keysAndValues[$i+1]
      }
      return [PSCustomObject] $htProps
    }
    $lines = @()
  } `
  -process {
    if ($_.trim() -ne '') { 
      $lines += $_
    } else {
      if ($lines) { toObj $lines }
      $lines = @()
    }
  } `
  -end {
    if ($lines) { toObj $lines }
  } | Format-Table

<强>解释

  • ForEach-Object%)与单独的beginprocessend块一起使用。

  • -begin,在开头执行一次

    • 定义辅助函数toObj(),它将一块连续的非空输入行转换为单个自定义对象。

      • toObj()将一行数组拆分为一系列连续的键值元素,将该数组转换为哈希表,然后将其转换为自定义对象。
    • 初始化数组$lines,它将存储单个连续非空输入行块的行

  • -process块,为每个输入行执行

    • 如果手头的输入行是非空的:将其添加到存储在数组$lines中的当前连续非空输入行块中。

    • 否则:将当前块提交到toObj()以转换为自定义对象,然后重置$lines数组以启动下一个块。实际上,每个段落(非空行的运行)都会调用toObj()

  • -end块,最后执行一次

    • 将最后一段提交至toObj()以转换为自定义对象。
  • 最后,生成的自定义对象数组将传递给Format-Table