替换文本需要是其输入在正则表达式中捕获的函数的输出
Replace text needs to be the output of a function whose input is capture in the regex
我正在编写一个 powershell 脚本来将日志文件转换为我可以更轻松地处理的格式。
输入文件由如下几行组成:
Mon Nov 10 10:00:44 2014
AVYRLYST_001_DIREDBU7_P201_6179726.ps.zip
Mon Nov 10 11:25:58 2014
ADMMPPST_001_DEPTMPP_P201_6179809.ps.zip
我需要文件在同一行上包含每个 .zip 文件的时间戳,但格式为 yyyymmddHHMMSS,例如
20141110100044 AVYRLYST_001_DIREDBU7_P201_6179726.ps.zip
20141110112558 ADMMPPST_001_DEPTMPP_P201_6179809.ps.zip
我正在使用 Shay Levy 的一个函数来帮助我从 string
到 DateTime
并相应地转换日期格式,并在我完成其余部分后尝试在替换中使用重新格式化。
但是,我正在努力从替换中获取捕获的输出用作函数的输入,并将其结果用作替换文本。
下面是我的代码:
function ConvertFrom-DateString
{
[OutputType('System.DateTime')]
[CmdletBinding(DefaultParameterSetName='Culture')]
param(
[Parameter(
Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
HelpMessage='A string containing a date and time to convert.'
)]
[System.String]$Value,
[Parameter(
Mandatory=$true,
Position=1,
HelpMessage='The required format of the date string value'
)]
[Alias('format')]
[System.String]$FormatString,
[Parameter(ParameterSetName='Culture')]
[System.Globalization.CultureInfo]$Culture=$null,
[Parameter(Mandatory=$true,ParameterSetName='InvariantCulture')]
[switch]$InvariantCulture
)
process
{
if($PSCmdlet.ParameterSetName -eq ‘InvariantCulture‘)
{
$Culture = [System.Globalization.CultureInfo]::InvariantCulture
}
Try
{
[System.DateTime]::ParseExact($Value,$FormatString,$Culture)
}
Catch [System.FormatException]
{
Write-Error “‘$Value’ is not in the correct format.“
}
Catch
{
Write-Error $_
}
}
<#
.SYNOPSIS
Converts a string representation of a date.
.DESCRIPTION
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format and culture-specific format
information. The format of the string representation must match the specified
format exactly.
.PARAMETER Value
A string containing a date and time to convert.
.PARAMETER FormatString
The required format of the date string value. If FormatString defines a
date with no time element, the resulting DateTime value has a time of
midnight (00:00:00).
If FormatString defines a time with no date element, the resulting DateTime
value has a date of DateTime.Now.Date.
If FormatString is a custom format pattern that does not include date or
time separators (such as “yyyyMMdd HHmm”), use the invariant culture
(e.g [System.Globalization.CultureInfo]::InvariantCulture), for the provider
parameter and the widest form of each custom format specifier.
For example, if you want to specify hours in the format pattern, specify
the wider form, “HH”, instead of the narrower form, “H”.
The format parameter is a string that contains either a single standard
format specifier, or one or more custom format specifiers that define the
required format of StringFormats. For details about valid formatting codes,
see ‘Standard Date and Time Format Strings’ (http://msdn.microsoft.com/en-us/library/az4se3k1.aspx)
or ‘Custom Date and Time Format Strings’ (http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx).
.PARAMETER Culture
An object that supplies culture-specific formatting information about the
date string value. The default value is null. A value of null corresponds
to the current culture.
.PARAMETER InvariantCulture
Gets the CultureInfo that is culture-independent (invariant). The invariant
culture is culture-insensitive. It is associated with the English language
but not with any country/region.
.EXAMPLE
ConvertFrom-DateString -Value ‘Sun 15 Jun 2008 8:30 AM -06:00′ -FormatString ‘ddd dd MMM yyyy h:mm tt zzz’ -InvariantCulture
Sunday, June 15, 2008 5:30:00 PM
This example converts the date string, ‘Sun 15 Jun 2008 8:30 AM -06:00′,
according to the specifier that defines the required format.
The InvariantCulture switch parameter formats the date string in a
culture-independent manner.
.EXAMPLE
‘jeudi 10 avril 2008 06:30′ | ConvertFrom-DateString -FormatString ‘dddd dd MMMM yyyy HH:mm’ -Culture fr-FR
Thursday, April 10, 2008 6:30:00 AM
In this example a date string, in French format (culture). The date string
is piped to ConvertFrom-DateString. The input value is bound to the Value
parameter. The FormatString value defines the required format of the date
string value. The result is a DateTime object that is equivalent to the date
and time contained in the Value parameter, as specified by FormatString and
Culture parameters.
.EXAMPLE
ConvertFrom-DateString -Value ‘Sun 15 Jun 2008 8:30 AM -06:00′ -FormatString ‘ddd dd MMM yyyy h:mm tt zzz’
Sunday, June 15, 2008 5:30:00 PM
Converts the date string specified in the Value parameter with the
custom specifier specified in the FormatString parameter. The result
DateTime object format corresponds to the current culture.
.INPUTS
System.String
You can pipe a string that contains a date and time to convert.
.OUTPUTS
System.DateTime
.NOTES
Author: Shay Levy
Blog : http://PowerShay.com
.LINK
http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx
#>
}
#Read History Log, joining lines with spaces to get datestamps on same lines as filenames
$content = (gc K:\RUN-THUND-PSPRD_PRD-History.log) -join " "
#Replace ".zip" with ".zip" with a carriage return on the end
$merged = $content -replace '.zip',".zip`r`n"
#Trim Leading and Trailing Spaces
$Trimmed = $merged.Trim() -replace ' ',''
<# find all timestamps and replace them with converted timestamp in yyyymmddHHMMSS format
e.g. to do this for one date string, the syntax would be:
'Sun Nov 09 13:19:09 2014' | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy' #>
$FixedTimeStamps = $Trimmed -replace '([A-Za-z]{3}\ [A-Za-z]{3}\ \d{2}\ \d{2}\:\d{2}\:\d{2}\ \d{4})',
("` | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'")
但是,我收到以下错误:
The term ' | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'' is not recognized as the name of a cmdlet, fun
ction, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is co
rrect and try again.
At K:\CodeSnippets\PowerShell\ThunderHead_To_XML.ps1:154 char:43
+ (& <<<< "` | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'")
+ CategoryInfo : ObjectNotFound: ( | ConvertFro... HH:mm:ss yyyy':String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
当我将最后一条命令的语法略微更改为$FixedTimeStamps = $Trimmed -replace '([A-Za-z]{3}\ [A-Za-z]{3}\ \d{2}\ \d{2}\:\d{2}\:\d{2}\ \d{4})',
("'``' | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'")
时,我没有收到任何错误,但文件条目最终如下所示:
Tue Jan 06 15:39:08 2015 |ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy' ADMMPPST_001_DEPTMPP_P201_6218715.ps
.zip
所以我觉得我离得不远了,这更令人沮丧!
感谢收到的任何帮助。
编辑
我仍然希望可以在替换命令中找到一种方法来执行此操作,所以我将保持打开状态。
但是,我同时重新访问了我的代码,并在函数定义之后使用了以下代码,它可靠地工作,尽管它在 foreach
循环中时有点慢:
#Read History Log
$content = (gc K:\RUN-THUND-PSPRD_PRD-History.log)
#Change the datestamp format:
#first use select-string to get a table of dates using a regex
$dates = $content|select-string -pattern '[A-Za-z]{3}\ [A-Za-z]{3}\ \d{2}\ \d{2}\:\d{2}\:\d{2}\ \d{4}'
#next go through each match in turn, converting the date string to a DateTime object,
#then use -f to format as string in required format
$dates | foreach {
$strolddate = $_.Line
$dtolddate = $strolddate|ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'
$strnewdate = '{0:yyyyMMddHHmmss}' -f $dtolddate
$content = $content -replace $strolddate,$strnewdate
}
#join lines with spaces to get datestamps on same lines as filenames
$content = $content -join " "
#Replace ".zip" with ".zip" with a carriage return on the end
$merged = $content -replace '.zip',".zip`r`n"
#Trim Leading and Trailing Spaces
$Trimmed = $merged.Trim() -replace ' ',''
对于 Powershell v2,我会这样做:
$x = Get-Content .\logfile.log
$x = (($x -join "|") -split "\|\|")
$x | % {
$i = ($_ -split '\|')
$i[0] = Get-Date ($i[0] -replace '^\w+ (\w+ \d+) (\d+:\d+:\d+) (\d+)$', ' ') -f 'yyyyMMddhhmmss'
$i[0] + ' ' + $i[1]
}
对于 Powershell V3,我会使用这个:
$x = (Get-Content .\logfile.log -Raw) -split "`n`n"
$x | % {
$i = ($_ -split "`n")
$i[0] = Get-Date ($i[0] -replace '^\w+ (\w+ \d+) (\d+:\d+:\d+) (\d+)$', ' ') -f 'yyyyMMddhhmmss'
$i[0] + ' ' + $i[1]
}
我正在编写一个 powershell 脚本来将日志文件转换为我可以更轻松地处理的格式。
输入文件由如下几行组成:
Mon Nov 10 10:00:44 2014
AVYRLYST_001_DIREDBU7_P201_6179726.ps.zip
Mon Nov 10 11:25:58 2014
ADMMPPST_001_DEPTMPP_P201_6179809.ps.zip
我需要文件在同一行上包含每个 .zip 文件的时间戳,但格式为 yyyymmddHHMMSS,例如
20141110100044 AVYRLYST_001_DIREDBU7_P201_6179726.ps.zip
20141110112558 ADMMPPST_001_DEPTMPP_P201_6179809.ps.zip
我正在使用 Shay Levy 的一个函数来帮助我从 string
到 DateTime
并相应地转换日期格式,并在我完成其余部分后尝试在替换中使用重新格式化。
但是,我正在努力从替换中获取捕获的输出用作函数的输入,并将其结果用作替换文本。
下面是我的代码:
function ConvertFrom-DateString
{
[OutputType('System.DateTime')]
[CmdletBinding(DefaultParameterSetName='Culture')]
param(
[Parameter(
Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
HelpMessage='A string containing a date and time to convert.'
)]
[System.String]$Value,
[Parameter(
Mandatory=$true,
Position=1,
HelpMessage='The required format of the date string value'
)]
[Alias('format')]
[System.String]$FormatString,
[Parameter(ParameterSetName='Culture')]
[System.Globalization.CultureInfo]$Culture=$null,
[Parameter(Mandatory=$true,ParameterSetName='InvariantCulture')]
[switch]$InvariantCulture
)
process
{
if($PSCmdlet.ParameterSetName -eq ‘InvariantCulture‘)
{
$Culture = [System.Globalization.CultureInfo]::InvariantCulture
}
Try
{
[System.DateTime]::ParseExact($Value,$FormatString,$Culture)
}
Catch [System.FormatException]
{
Write-Error “‘$Value’ is not in the correct format.“
}
Catch
{
Write-Error $_
}
}
<#
.SYNOPSIS
Converts a string representation of a date.
.DESCRIPTION
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format and culture-specific format
information. The format of the string representation must match the specified
format exactly.
.PARAMETER Value
A string containing a date and time to convert.
.PARAMETER FormatString
The required format of the date string value. If FormatString defines a
date with no time element, the resulting DateTime value has a time of
midnight (00:00:00).
If FormatString defines a time with no date element, the resulting DateTime
value has a date of DateTime.Now.Date.
If FormatString is a custom format pattern that does not include date or
time separators (such as “yyyyMMdd HHmm”), use the invariant culture
(e.g [System.Globalization.CultureInfo]::InvariantCulture), for the provider
parameter and the widest form of each custom format specifier.
For example, if you want to specify hours in the format pattern, specify
the wider form, “HH”, instead of the narrower form, “H”.
The format parameter is a string that contains either a single standard
format specifier, or one or more custom format specifiers that define the
required format of StringFormats. For details about valid formatting codes,
see ‘Standard Date and Time Format Strings’ (http://msdn.microsoft.com/en-us/library/az4se3k1.aspx)
or ‘Custom Date and Time Format Strings’ (http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx).
.PARAMETER Culture
An object that supplies culture-specific formatting information about the
date string value. The default value is null. A value of null corresponds
to the current culture.
.PARAMETER InvariantCulture
Gets the CultureInfo that is culture-independent (invariant). The invariant
culture is culture-insensitive. It is associated with the English language
but not with any country/region.
.EXAMPLE
ConvertFrom-DateString -Value ‘Sun 15 Jun 2008 8:30 AM -06:00′ -FormatString ‘ddd dd MMM yyyy h:mm tt zzz’ -InvariantCulture
Sunday, June 15, 2008 5:30:00 PM
This example converts the date string, ‘Sun 15 Jun 2008 8:30 AM -06:00′,
according to the specifier that defines the required format.
The InvariantCulture switch parameter formats the date string in a
culture-independent manner.
.EXAMPLE
‘jeudi 10 avril 2008 06:30′ | ConvertFrom-DateString -FormatString ‘dddd dd MMMM yyyy HH:mm’ -Culture fr-FR
Thursday, April 10, 2008 6:30:00 AM
In this example a date string, in French format (culture). The date string
is piped to ConvertFrom-DateString. The input value is bound to the Value
parameter. The FormatString value defines the required format of the date
string value. The result is a DateTime object that is equivalent to the date
and time contained in the Value parameter, as specified by FormatString and
Culture parameters.
.EXAMPLE
ConvertFrom-DateString -Value ‘Sun 15 Jun 2008 8:30 AM -06:00′ -FormatString ‘ddd dd MMM yyyy h:mm tt zzz’
Sunday, June 15, 2008 5:30:00 PM
Converts the date string specified in the Value parameter with the
custom specifier specified in the FormatString parameter. The result
DateTime object format corresponds to the current culture.
.INPUTS
System.String
You can pipe a string that contains a date and time to convert.
.OUTPUTS
System.DateTime
.NOTES
Author: Shay Levy
Blog : http://PowerShay.com
.LINK
http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx
#>
}
#Read History Log, joining lines with spaces to get datestamps on same lines as filenames
$content = (gc K:\RUN-THUND-PSPRD_PRD-History.log) -join " "
#Replace ".zip" with ".zip" with a carriage return on the end
$merged = $content -replace '.zip',".zip`r`n"
#Trim Leading and Trailing Spaces
$Trimmed = $merged.Trim() -replace ' ',''
<# find all timestamps and replace them with converted timestamp in yyyymmddHHMMSS format
e.g. to do this for one date string, the syntax would be:
'Sun Nov 09 13:19:09 2014' | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy' #>
$FixedTimeStamps = $Trimmed -replace '([A-Za-z]{3}\ [A-Za-z]{3}\ \d{2}\ \d{2}\:\d{2}\:\d{2}\ \d{4})',
("` | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'")
但是,我收到以下错误:
The term ' | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'' is not recognized as the name of a cmdlet, fun
ction, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is co
rrect and try again.
At K:\CodeSnippets\PowerShell\ThunderHead_To_XML.ps1:154 char:43
+ (& <<<< "` | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'")
+ CategoryInfo : ObjectNotFound: ( | ConvertFro... HH:mm:ss yyyy':String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
当我将最后一条命令的语法略微更改为$FixedTimeStamps = $Trimmed -replace '([A-Za-z]{3}\ [A-Za-z]{3}\ \d{2}\ \d{2}\:\d{2}\:\d{2}\ \d{4})',
("'``' | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'")
时,我没有收到任何错误,但文件条目最终如下所示:
Tue Jan 06 15:39:08 2015 |ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy' ADMMPPST_001_DEPTMPP_P201_6218715.ps
.zip
所以我觉得我离得不远了,这更令人沮丧!
感谢收到的任何帮助。
编辑
我仍然希望可以在替换命令中找到一种方法来执行此操作,所以我将保持打开状态。
但是,我同时重新访问了我的代码,并在函数定义之后使用了以下代码,它可靠地工作,尽管它在 foreach
循环中时有点慢:
#Read History Log
$content = (gc K:\RUN-THUND-PSPRD_PRD-History.log)
#Change the datestamp format:
#first use select-string to get a table of dates using a regex
$dates = $content|select-string -pattern '[A-Za-z]{3}\ [A-Za-z]{3}\ \d{2}\ \d{2}\:\d{2}\:\d{2}\ \d{4}'
#next go through each match in turn, converting the date string to a DateTime object,
#then use -f to format as string in required format
$dates | foreach {
$strolddate = $_.Line
$dtolddate = $strolddate|ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'
$strnewdate = '{0:yyyyMMddHHmmss}' -f $dtolddate
$content = $content -replace $strolddate,$strnewdate
}
#join lines with spaces to get datestamps on same lines as filenames
$content = $content -join " "
#Replace ".zip" with ".zip" with a carriage return on the end
$merged = $content -replace '.zip',".zip`r`n"
#Trim Leading and Trailing Spaces
$Trimmed = $merged.Trim() -replace ' ',''
对于 Powershell v2,我会这样做:
$x = Get-Content .\logfile.log
$x = (($x -join "|") -split "\|\|")
$x | % {
$i = ($_ -split '\|')
$i[0] = Get-Date ($i[0] -replace '^\w+ (\w+ \d+) (\d+:\d+:\d+) (\d+)$', ' ') -f 'yyyyMMddhhmmss'
$i[0] + ' ' + $i[1]
}
对于 Powershell V3,我会使用这个:
$x = (Get-Content .\logfile.log -Raw) -split "`n`n"
$x | % {
$i = ($_ -split "`n")
$i[0] = Get-Date ($i[0] -replace '^\w+ (\w+ \d+) (\d+:\d+:\d+) (\d+)$', ' ') -f 'yyyyMMddhhmmss'
$i[0] + ' ' + $i[1]
}