我需要从filezilla日志中提取日期,时间和文件名,以便将其插入数据库。
这是我到目前为止所做的:
Select-String "C:\Scripts\testing\SSIS\testfiles\fzs-2014-04-15.log" -Pattern "STOR" -AllMatches
Foreach($line in $lines){
$line = $line -replace "C:\Path-to-logs\filezilla.log.*\) ",""
$line = $line -replace "[AM|PM].* STOR ",""
$line -split " "
}
我得到以下结果:
C:\path-to-logs\filezilla.log:114:(003173) 4/15/2014 3:04:20 AM - cwwsfge (192.168.250)> STOR NewFileupload.TXT
C:\path-to-logs\filezilla.log.log:210:(000182) 4/15/2014 6:21:21 AM - refect(192.168.250)> STOR Testfile_20140415
C:\path-to-logs\filezilla.log.log:662:(000179) 4/15/2014 6:27:13 AM - refect (192.168.2)> STOR FreeMoney.txt
那么,如果我在foreach中获得该信息,该怎么办?
谢谢!
答案 0 :(得分:1)
编辑以匹配上述更改。我认为你仍然可以使用一个正则表达式-split,然后挑选你需要的元素。试试这个:
Foreach($line in $lines){
$parts = $line -split '\) | - |\> STOR |:\('
$logdate = [DateTime]::Parse($parts[2])
$filename = $parts[4]
write-host "Filename: $filename"
write-host "Filedate: $($logdate.Date.ToShortDateString())"
write-host "Filetime: $($logdate.TimeOfDay)`n"
}
基本上这是匹配“)”,“ - ”,“> STOR”或“:(”并将这些线分开。如果格式一致,每次传递中应该有5个元素。我添加了一些用于选择文件名并解析日期的代码,它会为上面示例中的值生成此值:
Filename: NewFileupload.TXT
Filedate: 4/15/2014
Filetime: 03:04:20
Filename: Testfile_20140415
Filedate: 4/15/2014
Filetime: 06:21:21
Filename: FreeMoney.txt
Filedate: 4/15/2014
Filetime: 06:27:13
答案 1 :(得分:0)
使用前面的答案,我构建了一个脚本,以制表符分隔的格式输出。
$logpath = "C:\Program Files (x86)\FileZilla Server\Logs"
# combine all the logs into one file
gci "$logpath\*.log" | sort LastWriteTime | % {$(Get-Content $_)} | Set-Content "$logpath\combo.txt"
# scan lines only containing login,file upload, and download
$lines = Select-String "$logpath\combo.txt" -Pattern "> RETR|> STOR|230 Logged on" -AllMatches
Foreach($line in $lines){
$parts = $line -split '\) | - |\> |:\('
$logdate = [DateTime]::Parse($parts[2])
$filename = $parts[4].Replace("230 Logged","Logged")
$user = $parts[3]
$user,$filename,$logdate -join "`t" | Out-File -FilePath "$logpath\output.txt" -Append -Width 500
}
答案 2 :(得分:0)
我创建了一个脚本来将日志解析为一种表单,该表单更易于使用/在这里与其他对OP有类似要求的人共享。
对于特定问题,下面是如何使用此代码:
[string[]]$logs = @('C:\Scripts\testing\SSIS\testfiles\fzs-2014-04-15.log') # you could add more / get these via Get-ChildItem / etc
[PSCustomObject[]]$data = $logs |
Get-FzLogData |
ForEach-Object {
if($_.Msg -match '\s*STOR\s(?<Filename>.+)') {
[PSCustomObject]@{
FileName = $Matches['FileName']
DateTime = $_.DateTime
}
}
}
$data # just shows the data for now...
完整代码:
class FzLogEntry {
[long]$SessionId
[DateTime]$DateTime
[string]$User
[version]$ClientIp # I've used version assuming it's always IPv4... if that assumption's wrong we may have to amend to string
[string]$Msg
FzLogEntry(){}
}
Function Get-FzLogData {
[OutputType('FzLogEntry[]')]
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string[]]$Path
)
Process {
foreach ($p in $Path) {
Get-Content -Path $p | ConvertTo-FzLogEntry
}
}
}
Function ConvertTo-FzLogEntry {
[OutputType('FzLogEntry')]
[CmdletBinding(DefaultParameterSetName = 'Default')]
Param (
[Parameter(ParameterSetName = 'Default', Mandatory = $true, ValueFromPipeline = $true)]
[Parameter(ParameterSetName = 'Unparsable', Mandatory = $true, ValueFromPipeline = $true)]
[string[]]$Line
,
[Parameter(ParameterSetName = 'Unparsable', Mandatory = $true)] # I don't really have a need for this; but it may be helpful if debugging to know when lines are not processed / have a gap in your results...
[Switch]$IncludDefaultForUnparsable
,
[Parameter(ParameterSetName = 'Unparsable')]
[FzLogEntry]$DefaultValue = $null
)
Begin {
[string]$regexPattern = @'
^\(
(?<SessionId>\d+)
\)\s
(?<DateTime>\S+\s\S+)
\s\-\s
(?<User>(?:\([^\)]+\))|(?:\S+))
\s\(
(?<ClientIp>[^>]+)
\)>\s*
(?<Msg>.*)
$
'@ -replace '[\r\n]+', ''
}
Process {
foreach ($l in $Line) {
if ($l -match $regexPattern) {
$fiddle = $Matches
$fiddle.Remove(0)
$fiddle.DateTime = $fiddle.DateTime -replace '^(\d+)\/(\d+)\/(\d+)', '$3-$2-$1' #correct date format to something that PS can auto convert to a DateTime. Assumes dd/mm/yyyy format in the logs
[FzLogEntry]$fiddle
} else {
if ($IncludDefaultForUnparsable.IsPresent) {
$DefaultValue
}
}
}
}
}
如果我对此功能进行任何更改,相关的Gist将保持最新。