如何将 RTF 格式的日志文件转换为纯文本
How to convert a log file that is an RTF format to plain text
我需要将备份解决方案应用程序生成的日志文件从 RTF 格式连续转换为纯文本格式(如制作一个全新的日志,它是那个始终是更新副本的日志的精确副本) 以便使用我从另一个用户那里得到的代码解析日志文件中的错误(请在下面找到)。知道如何使用 powershell 对代码执行此操作吗?
我拥有的可以搜索文本文件的代码:
$daysBack = 3
$refDate = (Get-Date).AddDays(-$daysBack).Date # set this to midnight
$log = Get-Content -Path 'C:\Users\<User>\Documents\TheLog.log'
# find lines that start with what looks like a date and contains 'Errors:'
# capture the date part in backreference $matches[1] to parse into a real datetime object for comparison with $refDate
$errors = @($log | Where-Object { $_ -match '(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}).*Errors:' } |
Where-Object { [datetime]::ParseExact($matches[1], 'dd/MM/yyyy HH:mm:ss', $null) -ge $refDate }).Count
# if $errors not 0
if ($errors) {
$count = if ($errors -eq 1) { "was an error" } else { "were $errors errors" }
"There {0} in your back up solution in the last $daysBack days. Please check your log file." -f $count
}
else {
"There were no errors in backing up your files in the last $daysBack days."
}
我已经使用以下日志文件的纯文本文件版本进行了测试:
18/02/2021 08:57:37 - can not access C:\users\<username>\documents\ The network path was not found.
18/02/2021 08:57:37 - End: Documents... copied: 0, Errors: 1
21/02/2021 08:57:37 - can not access C:\users\<username>\documents\ The network path was not found.
21/02/2021 08:57:37 - End: Documents... copied: 0, Errors: 1
22/02/2021 17:27:33 - Begin: Documents=======================================
22/02/2021 17:27:33 - copied Notes.docx from C:\users\<username>\documents\ to D:\users\<username>\documents\
22/02/2021 17:27:33 - End: Documents...Copied 1
22/02/2021 17:27:33 - End: Documents...Copied 1, Deleted: 1
以上代码不适用于 RTF。任何帮助或任何想法如何更改上述代码以适合我的 RTF 格式的日志文件?
使用@THEO 的以下代码:)
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:41 char:13
+ $word.Quit()
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:42 char:13
+ $null = [System.Runtime.InteropServices.Marshal]::Release ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:43 char:13
+ $null = [System.Runtime.InteropServices.Marshal]::Release ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:44 char:13
+ [System.GC]::Collect()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:45 char:13
+ [System.GC]::WaitForPendingFinalizers()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot set property. Property setting is supported only on core types in this language mode.
At line:17 char:9
+ $word.Visible = $false
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertySetterNotSupportedInConstrainedLanguage
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:55 char:31
+ $log = Get-Content -Path $plainTextLog
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentC
ommand
要将 RTF 文件转换为纯文本文件,您可以使用以下辅助函数:
function ConvertFrom-RTF {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[Alias('FullName')]
[string]$Path
)
# this is the output format
# see: https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.word.wdsaveformat?view=word-pia
$WdSaveFormat = 3 # wdFormatTextLineBreaks
try {
$word = New-Object -ComObject Word.Application
$word.Visible = $false
$doc = $word.Documents.Open($Path)
# Replace the source file extenson with the appropriate target file extension
$fileOut = [System.IO.Path]::ChangeExtension($Path, '.txt')
if (Test-Path -Path $fileOut -PathType Leaf) {
# Delete existing file
Remove-Item -Path $fileOut -Force -Confirm:$false
}
# Check Version of Office Installed. Pre 2010 versions need [ref] on the parameters
if ($word.Version -gt '14.0') {
$doc.SaveAs($fileOut, $WdSaveFormat)
}
else {
$doc.SaveAs([ref]$fileOut,[ref]$WdSaveFormat)
}
$doc.Close($false)
# return the filename of the converted file
return $fileOut
}
finally {
# cleanup code
if ($word) {
$word.Quit()
$null = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($doc)
$null = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($word)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
}
}
# the returned value is the full path and filename of the converted text file
$plainTextLog = ConvertFrom-RTF -Path 'C:\Users\<User>\Documents\TheLog.rtf'
在此之下,添加您已经从 获得的代码来解析日志:
$daysBack = 3
$refDate = (Get-Date).AddDays(-$daysBack).Date # set this to midnight
$log = Get-Content -Path $plainTextLog
# find lines that start with what looks like a date and contains 'Errors:'
# capture the date part in backreference $matches[1] to parse into a real datetime object for comparison with $refDate
$errors = @($log | Where-Object { $_ -match '(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}).*Errors:' } |
Where-Object { [datetime]::ParseExact($matches[1], 'dd/MM/yyyy HH:mm:ss', $null) -ge $refDate }).Count
# if $errors not 0
if ($errors) {
$count = if ($errors -eq 1) { "was an error" } else { "were $errors errors" }
"There {0} in your back up solution in the last $daysBack days. Please check your log file." -f $count
}
else {
"There were no errors in backing up your files in the last $daysBack days."
}
我需要将备份解决方案应用程序生成的日志文件从 RTF 格式连续转换为纯文本格式(如制作一个全新的日志,它是那个始终是更新副本的日志的精确副本) 以便使用我从另一个用户那里得到的代码解析日志文件中的错误(请在下面找到)。知道如何使用 powershell 对代码执行此操作吗?
我拥有的可以搜索文本文件的代码:
$daysBack = 3
$refDate = (Get-Date).AddDays(-$daysBack).Date # set this to midnight
$log = Get-Content -Path 'C:\Users\<User>\Documents\TheLog.log'
# find lines that start with what looks like a date and contains 'Errors:'
# capture the date part in backreference $matches[1] to parse into a real datetime object for comparison with $refDate
$errors = @($log | Where-Object { $_ -match '(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}).*Errors:' } |
Where-Object { [datetime]::ParseExact($matches[1], 'dd/MM/yyyy HH:mm:ss', $null) -ge $refDate }).Count
# if $errors not 0
if ($errors) {
$count = if ($errors -eq 1) { "was an error" } else { "were $errors errors" }
"There {0} in your back up solution in the last $daysBack days. Please check your log file." -f $count
}
else {
"There were no errors in backing up your files in the last $daysBack days."
}
我已经使用以下日志文件的纯文本文件版本进行了测试:
18/02/2021 08:57:37 - can not access C:\users\<username>\documents\ The network path was not found.
18/02/2021 08:57:37 - End: Documents... copied: 0, Errors: 1
21/02/2021 08:57:37 - can not access C:\users\<username>\documents\ The network path was not found.
21/02/2021 08:57:37 - End: Documents... copied: 0, Errors: 1
22/02/2021 17:27:33 - Begin: Documents=======================================
22/02/2021 17:27:33 - copied Notes.docx from C:\users\<username>\documents\ to D:\users\<username>\documents\
22/02/2021 17:27:33 - End: Documents...Copied 1
22/02/2021 17:27:33 - End: Documents...Copied 1, Deleted: 1
以上代码不适用于 RTF。任何帮助或任何想法如何更改上述代码以适合我的 RTF 格式的日志文件?
使用@THEO 的以下代码:)
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:41 char:13
+ $word.Quit()
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:42 char:13
+ $null = [System.Runtime.InteropServices.Marshal]::Release ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:43 char:13
+ $null = [System.Runtime.InteropServices.Marshal]::Release ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:44 char:13
+ [System.GC]::Collect()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:45 char:13
+ [System.GC]::WaitForPendingFinalizers()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
Cannot set property. Property setting is supported only on core types in this language mode.
At line:17 char:9
+ $word.Visible = $false
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertySetterNotSupportedInConstrainedLanguage
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:55 char:31
+ $log = Get-Content -Path $plainTextLog
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentC
ommand
要将 RTF 文件转换为纯文本文件,您可以使用以下辅助函数:
function ConvertFrom-RTF {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[Alias('FullName')]
[string]$Path
)
# this is the output format
# see: https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.word.wdsaveformat?view=word-pia
$WdSaveFormat = 3 # wdFormatTextLineBreaks
try {
$word = New-Object -ComObject Word.Application
$word.Visible = $false
$doc = $word.Documents.Open($Path)
# Replace the source file extenson with the appropriate target file extension
$fileOut = [System.IO.Path]::ChangeExtension($Path, '.txt')
if (Test-Path -Path $fileOut -PathType Leaf) {
# Delete existing file
Remove-Item -Path $fileOut -Force -Confirm:$false
}
# Check Version of Office Installed. Pre 2010 versions need [ref] on the parameters
if ($word.Version -gt '14.0') {
$doc.SaveAs($fileOut, $WdSaveFormat)
}
else {
$doc.SaveAs([ref]$fileOut,[ref]$WdSaveFormat)
}
$doc.Close($false)
# return the filename of the converted file
return $fileOut
}
finally {
# cleanup code
if ($word) {
$word.Quit()
$null = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($doc)
$null = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($word)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
}
}
# the returned value is the full path and filename of the converted text file
$plainTextLog = ConvertFrom-RTF -Path 'C:\Users\<User>\Documents\TheLog.rtf'
在此之下,添加您已经从
$daysBack = 3
$refDate = (Get-Date).AddDays(-$daysBack).Date # set this to midnight
$log = Get-Content -Path $plainTextLog
# find lines that start with what looks like a date and contains 'Errors:'
# capture the date part in backreference $matches[1] to parse into a real datetime object for comparison with $refDate
$errors = @($log | Where-Object { $_ -match '(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}).*Errors:' } |
Where-Object { [datetime]::ParseExact($matches[1], 'dd/MM/yyyy HH:mm:ss', $null) -ge $refDate }).Count
# if $errors not 0
if ($errors) {
$count = if ($errors -eq 1) { "was an error" } else { "were $errors errors" }
"There {0} in your back up solution in the last $daysBack days. Please check your log file." -f $count
}
else {
"There were no errors in backing up your files in the last $daysBack days."
}