格式化日志输出

时间:2015-08-19 15:18:14

标签: powershell logging formatting

我的脚本正在备份多个SQL Server数据库,并将每个数据库和文件名输出到日志文件中。我不确定如何以列格式对齐它们。

Function LogWrite
{
  Param ([string]$logstring)
  Add-content $Logfile -value $logstring
}


$server = new-object ("Microsoft.SQLServer.Management.Smo.Server")  "(Local)\sqlexpress"
$databases = $server.databases

$array = @($db1,$db2,$db3,$db4,$db5,$db6,$db7,$db8,$db9,$db10,$db11)
foreach ($element in $array)
{
  foreach ($db in $databases)
  {
    if($db.Name -like $element)
    {
      $dbname = $db.Name
      $dateTime = get-date -format yyyy_MM_dd
      $fullBackupFilePath = ($backupDirectory + "\" + $dbname + "_FULL_" + $dateTime + ".bak")

      Backup-SQLDatabase -ServerInstance $sqlServer -Database $dbname -BackupFile $fullBackupFilePath

      LogWrite "$dbname   -    $backupDirectory"
    }
  }
}

目前的情况如下:

Databases Succesfully Backed Up:

Aqm       C:\Mappa_Backup\FULL
Atlas       C:\Mappa_Backup\FULL
halive       C:\Mappa_Backup\FULL
hatrafficinfo       C:\Mappa_Backup\FULL
jtr       C:\Mappa_Backup\FULL
jtr2       C:\Mappa_Backup\FULL
mappa       C:\Mappa_Backup\FULL
mtf       C:\Mappa_Backup\FULL
PartOneClaims       C:\Mappa_Backup\FULL
ptfeedback       C:\Mappa_Backup\FULL


The following files were deleted as they were older than 14 days:

Aqm_FULL_2015_08_19.bak
Atlas_FULL_2015_08_19.bak
halive_FULL_2015_08_19.bak
hatrafficinfo_FULL_2015_08_19.bak
jtr2_FULL_2015_08_19.bak
jtr_FULL_2015_08_19.bak
mappa_FULL_2015_08_19.bak
mtf_FULL_2015_08_19.bak
PartOneClaims_FULL_2015_08_19.bak
ptfeedback_FULL_2015_08_19.bak

5 个答案:

答案 0 :(得分:3)

您可以使用自定义PSObject。

{{1}}

答案 1 :(得分:3)

另一个简单的选择是使用.NET格式化指令,例如:

LogWrite ("{0,20}   -    {1,-60}" -f $dbname,$backupDirectory)

格式说明符为{<placeholder-number>,[- for left-align]<field-width>}

答案 2 :(得分:1)

您可以使用哈希表并使用format-table cmdlet显示它。

UIView

输出结果如下:

enter image description here

答案 3 :(得分:1)

你也可以用填充做一些简单的事情。

LogWrite "$($dbname.padright(20)) $BackupDirectory"

答案 4 :(得分:0)

有几种方法可以在PowerShell中对齐文本。最简单的方法是使用标签分隔元素

LogWrite "$dbname`t$backupDirectory"

这会得到这样的东西:

Aqm     C:\Mappa_Backup\FULL
Atlas   C:\Mappa_Backup\FULL
halive  C:\Mappa_Backup\FULL
hatrafficinfo   C:\Mappa_Backup\FULL
jtr     C:\Mappa_Backup\FULL
jtr2    C:\Mappa_Backup\FULL
mappa   C:\Mappa_Backup\FULL
mtf     C:\Mappa_Backup\FULL
PartOneClaims   C:\Mappa_Backup\FULL
ptfeedback      C:\Mappa_Backup\FULL

这不会完美地对齐列,但比以前更好,并且您得到制表符分隔文件,您可以使用其他工具轻松处理,而无需解析每行中的值(如果需要进一步处理)的/所需的)。

如果您的日志文件中必须有对齐的列,则可以(建议@PeterSchneider)创建自定义对象,只要它们的属性少于5个,就会自动以表格格式显示:

$prop = [ordered]@{
  DBName          = $dbname
  BackupDirectory = $backupDirectory
}
$obj = New-Object -Type PSCustomObject -Property $prop | Out-String
LogWrite $obj

会创建如下的日志条目:

DBName                                              BackupDirectory
------                                              ---------------
Aqm                                                 C:\Mappa_Backup\FULL

DBName                                              BackupDirectory
------                                              ---------------
Atlas                                               C:\Mappa_Backup\FULL

...

或者像这样删除Out-String

@{DBName=Aqm; BackupDirectory=C:\Mappa_Backup\FULL}
@{DBName=Atlas; BackupDirectory=C:\Mappa_Backup\FULL}
...

但这种方法有几个缺点。例如,除非您回显循环内的对象并让您的日志记录功能从循环外的管道读取其输入,否则您将获得写入文件的每一行的标题。这还需要将foreach循环更改为ForEach-Object

Function LogWrite {
  Param ([Parameter(ValueFromPipeline=$true)][string]$logstring)
  Process {
    Add-content 'C:\temp\out.txt' -value $logstring
  }
}

...

$databases | ForEach-Object {
  ...

  $prop = [ordered]@{
    DBName          = $dbname
    BackupDirectory = $backupDirectory
  }
  New-Object -Type PSCustomObject -Property $prop
} | Out-String | LogWrite

此外,列宽可能在运行之间有所不同,并且值可能会根据其长度被截断。另外,如果对象具有5个或更多属性,则自动格式更改为列表格式,因此您需要额外的Format-Table来维护表格输出。

根据format operator的建议,获取对齐列的最佳方法是使用@KeithHill-f):

LogWrite ('{0,-20} {1,-60}' -f $dbname, $backupDirectory)

每组花括号中的第一个数字是参数的索引(0表示第一个参数,此处为$dbname,1表示第二个,依此类推),第二个数字定义列宽。减号使列与左侧对齐。没有它,列就会向右对齐。