作为PowerShell编码的新手,我在PowerShell正则表达式模式中扩展变量时遇到了一些困难。
我想做的是:
该日期存储在变量$filedate
中。
然后去每行logfiles
每当我找到一条如下所示的行:
14:00:15 blablabla
在名为blabla20130620.log
的文件中
我希望数据线变为
2013-06-20 14:00:15 blablabla
它应该将附加模式的输出写入文本文件(以连接不同的日志文件)
这是我到现在为止所做的事情(我现在正在沙盒中测试,所以没有评论等......)
$Logpath = "o:\Log"
$prevcheck="2013-06-24 19:27:14"
$currenttd="{0:yyyy-MM-dd HH:mm:ss}" -f (get-date)
$batch = 1000
[regex]$match_regex = '^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)'
If (Test-Path "$Logpath\test.txt"){
Remove-Item "$Logpath\test.txt"
}
$files=Get-ChildItem $LogPath\*.log | Where-Object { $_.LastWriteTime -ge "$prevcheck" - and $_.LastWriteTime -le "$currenttd" -and !$_.PSIsContainer }
foreach ($file in $files)
{
$filedate=$file.Name.Substring(6,4) + "-" + $file.Name.Substring(10,2) + "-" + $file.Name.Substring(12,2)
## This doesn't seem to work fine
## results look like:
## "$filedate" 14:00:15 blablabla
$replace_regex = '"$filedate" $_'
## I tried this too, but without success
## The time seems to dissappear now
## results look like:
## 2013-06-20 blablabla
#$replace_regex = iex('$filedate' + $_)
(Get-Content $file.PSPath -ReadCount $batch) |
foreach-object {if ($_ -match $match_regex) { $_ -replace $match_regex, $replace_regex} else { $_ }}|
out-file -Append "o:\log\test.txt"
答案 0 :(得分:1)
在PowerShell中,字符串必须是双引号("
)才能进行变量替换。单引号('
)字符串不执行变量替换。
在你的脚本中(我建议你缩进代码块的内容以使结构更容易理解):
$replace_regex = '"$filedate" $_'
其中字符串是单引号,因此没有变量替换。这可以通过记住反引号(`
)字符来解决,该字符可用于转义双引号字符串中嵌入的双引号:
$replace_regex = "`"$filedate`" $_"
但请记住:
$
是一个正则表达式元字符,因此如果您想在双引号中的正则表达式中包含$
,则需要对其进行转义以避免PSH将其视为变量的开头名称[regex]::Escape(string)
)。答案 1 :(得分:0)
你的事情过于复杂。
您正在比较Where-Object
过滤器中的日期,因此您无需将参考日期转换为字符串。只需使用日期:
$prevcheck = Get-Date "2013-06-24 19:27:14"
$currenttd = Get-Date
您可以使用正则表达式从文件名中提取日期并将其转换为所需的格式:
$filedate = $file.BaseName -replace '^.*(\d{4})(\d{2})(\d{2})$', '$1-$2-$3'
用于匹配时间的正则表达式过于正确。请改用^(\d{2}:\d{2}:\d{2})
。它有点邋,,但它很可能就足够了,并且更容易看到它。
要在日期前加上时间匹配,请使用"$filedate `$1"
。双引号将导致$filedate
从文件名扩展到日期,并且转义的$
(``$ 1`)将保持分组匹配(请参阅Richard的说明)。
虽然您可以将每个步骤的结果分配给变量,但使用单个管道更简单。
试试这个:
$Logpath = "o:\Log"
$Logfile = "$Logpath\test.txt"
$prevcheck = Get-Date "2013-06-24 19:27:14"
$currenttd = Get-Date
If (Test-Path -LiteralPath $Logfile) { Remove-Item $Logfile }
Get-ChildItem "$LogPath\*.log" | ? {
-not $_.PSIsContainer -and
$_.LastWriteTime -ge $prevcheck -and
$_.LastWriteTime -le $currenttd
} | % {
$filedate = $_.BaseName -replace '^.*(\d{4})(\d{2})(\d{2})$', '$1-$2-$3'
Get-Content $_ | % {
$_ -replace '^(\d{2}:\d{2}:\d{2})', "$filedate `$1"
} | Out-File -Append $Logfile
}