替换文本需要是其输入在正则表达式中捕获的函数的输出

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 的一个函数来帮助我从 stringDateTime 并相应地转换日期格式,并在我完成其余部分后尝试在替换中使用重新格式化。

但是,我正在努力从替换中获取捕获的输出用作函数的输入,并将其结果用作替换文本。

下面是我的代码:

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]
}