编辑:2013年12月19日
我未能恰当地定义可能引起混淆的输入,对此感到抱歉。输入文件是IIS日志,格式化需要保持不变。这些字段看起来像这样; “字段:日期时间s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent)cs(Referer)sc-status sc-substatus sc-win32-状态时间“
网址GET会显示这样的内容;
2013-12-07 00:23:50 XXX.XXX.XXX.XXX POST / code = 5071 80 - XXX.XXX.XXX.XXX Mozilla / 4.0 +(兼容; + MSIE + 8.0; +的Windows NT + 5.1 + +三叉戟/ 4.0; + NET + CLR 2.0.50727 +; + NET + CLR + 3.0.4506.2152; + NET + CLR + 3.5.30729; + NET4.0C; + NET4 .0E)http://blah.blah.com/?code=5071 200 0 64 3478
“code = 5071”帮助我们识别网址,如果我们删除所有其他网址,我们就可以运行统计工具并查找有多少匹配等等。
当时,在编码方面我是一个全新的,所以随意嘲笑。我正在尝试获取一个日志文件并根据多个变量删除行,我想我可以创建一个数组,这样只需要删除或添加一个数字就可以编辑一个文件。输入文件是一个简单的日志,包含几个字段,其中一个是“ID”,所以类似于; ddmmyy blah blah ID。该ID是一个十位数字,其中有三十七个。目的是读取日志,去掉所有不匹配的ID,然后将结果输出到新的日志文件。
此代码工作正常,但似乎在停止之前我只能有大约十四个“ - 并且”
Get-Content .\combined.log | Where-Object{$_-NotMatch '10011250' -And $_-NotMatch '10005816' -And $_-NotMatch '5077'} |Set-Content combined1.log
我拖着网,学会尽可能多地处理数组,但似乎没有任何效果,我知道这是我以及我如何设置它。我觉得这样的事可能有用;
$a = @(10011250, 10005816, 14200712, 2418, 10005699, 5071, 10001040, 4814, 10025390, 4175, 10005940, 10000040, 10008181)
Get-Content .\combined.log | ForEach($i in $a) {Where-Object{$_-notcontains $a}}| Set-Content combined1.log
正如你所知,这远远不是我的专业领域。有什么建议吗?
答案 0 :(得分:3)
您可以使用正则表达式中的替换在同一匹配操作中测试多个值。分隔多个值以匹配管道符号(|)。
Get-Content .\combined.log | Where-Object{$_-NotMatch '10011250|10005816'}
将过滤掉与10011250或10005816匹配的所有行 此外,-match运算符将立即匹配整个数组,并返回满足条件的成员。
试试这个:
$a = @(10011250, 10005816, 14200712, 2418, 10005699, 5071, 10001040, 4814, 10025390, 4175, 10005940, 10000040, 10008181)
$regex = [regex]($a -join '|')
Get-Content .\combined.log -ReadCount 1000 |
foreach {$_ -notmatch $regex | Add-Content combined1.log}
对于BACON:
$lines = (
'Line containing 10011250',
'Line containing 10005816',
'Line containing 10011250',
'Line containing 10915816'
)
$lines -notmatch '10011250|10005816'
Line containing 10915816
答案 1 :(得分:0)
假设每一行以空白字符结尾,后跟整数ID,您可以使用:
$excludedIds = 10011250, 10005816, 14200712, 2418, 10005699, 5071, 10001040, `
4814, 10025390, 4175, 10005940, 10000040, 10008181;
# Build a pattern from $excludedIds that matches one or more whitespace `
# characters followed by one of the above IDs followed by the end of the line
# Example: '\s+(10011250|10005816|14200712|...)$'
$excludedPattern = '\s+(' + ($excludedIds -join '|') + ')$';
Select-String -Path '.\combined.log' -Pattern $excludedPattern -NotMatch `
| Select-Object -ExpandProperty 'Line' `
| Set-Content -Path 'combined1.log';
Select-String
cmdlet将为不排除ID的每一行返回MatchInfo
class的实例。我们使用Select-Object
cmdlet检索Line
property,代表每个MatchInfo
的原始文本行。
请注意,我专门在该行的最后搜索整个ID。如果我没有这样做,我可能错误地匹配一个ID是另一个的子串。也就是说,以下一行......
161213 Field1 Field2 10915816
...匹配模式'915'
但不匹配'\s+915$'
(空格后跟字符串'915'
,后跟行尾)。这是我建议您仔细检查原始代码的行为,因为您可能会过滤掉部分但不完全匹配的ID,这可能是不可取的。
如果每行的第二个和第三个字段不包含任何空格,除了过滤之外,您还需要对每一行进行额外处理,这可能对您更有效:
$excludedIds = 10011250, 10005816, 14200712, 2418, 10005699, 5071, 10001040, `
4814, 10025390, 4175, 10005940, 10000040, 10008181;
$records = Import-Csv -Delimiter ' ' -Header 'Date', 'Field1', 'Field2', 'ID' -Path '.\combined.log' `
| Where-Object { $excludedIds -notcontains $_.ID; };
然后, $records
将包含已过滤的对象列表,每个对象都包含相应的Date
,Field1
,Field2
和ID
属性。不幸的是,原始的文本行现在丢失了,所以你必须自己重建它(或使用你想要的任何输出格式):
$records `
| ForEach-Object { "$($_.Date) $($_.Field1) $($_.Field2) $($_.ID)"; } `
| Set-Content -Path 'combined1.log';
答案 2 :(得分:0)
不要过度复杂化。
$array = @(10011250, 10005816, 14200712, 2418, 10005699, 5071, 10001040, 4814, 10025390, 4175,
10005940, 10000040, 10008181)
$file = ".\test.txt"
$log = Get-Content $file
ForEach ($line in $log) {
ForEach ($item in $array) {
if ($line -match "\b$($item)\b") {
$good_lines += @($line)
}
}
}
$good_lines | Set-content ".\Combined1.log"
$array = @(10011250, 10005816, 14200712, 2418, 10005699, 5071, 10001040, 4814, 10025390, 4175,
10005940, 10000040, 10008181)
$file = ".\test.txt"
$log = Get-Content $file
Write-Host "`n`n-- FILE LOADED: $((Get-Item $file).fullname)" -ForegroundColor "White"
ForEach ($line in $log) {
Write-Host "`n-- READING LINE: $line" -ForegroundColor "Yellow"
ForEach ($item in $array) {
sleep -milliseconds 100
Write-Host "-- COMPARING: $item ..." -nonewline -ForegroundColor "Cyan"
if ($line -match "\b$($item)\b") {
Write-Host "MATCH" -ForegroundColor "Green"
$good_lines += @($line)
}
else {
Write-Host "NO MATCH" -ForegroundColor "Red"
}
}
}
$good_lines | Set-content ".\Combined1.log"