【问题标题】:Powershell - convert log file to CSVPowershell - 将日志文件转换为 CSV
【发布时间】:2011-02-19 01:48:49
【问题描述】:

我的日志文件看起来像这样...

2009-12-18T08:25:22.983Z     1         174 dns:0-apr-credit-cards-uk.pedez.co.uk P http://0-apr-credit-cards-uk.pedez.co.uk/ text/dns #170 20091218082522021+89 sha1:AIDBQOKOYI7OPLVSWEBTIAFVV7SRMLMF - -
2009-12-18T08:25:22.984Z     1           5 dns:0-60racing.co.uk P http://0-60racing.co.uk/ text/dns #116 20091218082522037+52 sha1:WMII7OOKYQ42G6XPITMHJSMLQFLGCGMG - -
2009-12-18T08:25:23.066Z     1          79 dns:0-addiction.metapress.com.wam.leeds.ac.uk P http://0-addiction.metapress.com.wam.leeds.ac.uk/ text/dns #042 20091218082522076+20 sha1:NSUQN6TBIECAP5VG6TZJ5AVY34ANIC7R - -
...plus millions of other records

我需要将这些转换成 csv 文件...

"2009-12-18T08:25:22.983Z","1","174","dns:0-apr-credit-cards-uk.pedez.co.uk","P","http://0-apr-credit-cards-uk.pedez.co.uk/","text/dns","#170","20091218082522021+89","sha1:AIDBQOKOYI7OPLVSWEBTIAFVV7SRMLMF","-","-"
"2009-12-18T08:25:22.984Z","1","5","dns:0-60racing.co.uk","P","http://0-60racing.co.uk/","text/dns","#116","20091218082522037+52","sha1:WMII7OOKYQ42G6XPITMHJSMLQFLGCGMG","-","-"
"2009-12-18T08:25:23.066Z","1","79","dns:0-addiction.metapress.com.wam.leeds.ac.uk","P","http://0-addiction.metapress.com.wam.leeds.ac.uk/","text/dns","#042","20091218082522076+20","sha1:NSUQN6TBIECAP5VG6TZJ5AVY34ANIC7R","-","-"

字段分隔符可以是单个或多个空格字符,具有固定宽度和可变宽度字段。这往往会使我发现的大多数 CSV 解析器感到困惑。

最终我想将这些文件 bcp 到 SQL Server 中,但您只能指定单个字符作为字段分隔符(即 ' '),这会破坏固定长度的字段。

到目前为止 - 我正在使用 PowerShell

gc -ReadCount 10 -TotalCount 200 .\crawl_sample.log | foreach { ([regex]'([\S]*)\s+').matches($_) } | foreach {$_.Groups[1].Value}

这会返回一个字段流:

2009-12-18T08:25:22.983Z
1
74
dns:0-apr-credit-cards-uk.pedez.co.uk
P
http://0-apr-credit-cards-uk.pedez.co.uk/
text/dns
#170
20091218082522021+89
sha1:AIDBQOKOYI7OPLVSWEBTIAFVV7SRMLMF
-
-
2009-12-18T08:25:22.984Z
1
55
dns:0-60racing.co.uk
P
http://0-60racing.co.uk/
text/dns
#116
20091218082522037+52
sha1:WMII7OOKYQ42G6XPITMHJSMLQFLGCGMG
-

但是如何将该输出转换为 CSV 格式?

【问题讨论】:

  • 你可能想看看我的 FOSS CSV 修改工具code.google.com/p/csvfix,我认为它可以做你想做的事,但只能作为一个多阶段的过程。

标签: powershell csv


【解决方案1】:

再次回答我自己的问题...

measure-command {
    $q = [regex]" +"
    $q.Replace( ([string]::join([environment]::newline, (Get-Content -ReadCount 1 \crawl_sample2.log))), "," ) > crawl_sample2.csv
}

而且很快!

观察:

  • 我使用 \s+ 作为正则表达式分隔符,这打破了换行符
  • Get-Content -ReadCount 1 将单行数组流式传输到正则表达式
  • 然后将输出字符串通过管道传输到新文件

更新

此脚本有效,但在处理大文件时会使用大量 RAM。那么,如果不使用 8GB 的​​ RAM 和交换,我怎么能做同样的事情呢!

我认为这是由 join 再次缓冲所有数据引起的......有什么想法吗?

更新 2

好的 - 有一个更好的解决方案...

Get-Content -readcount 100 -totalcount 100000 .\crawl.log | 
    ForEach-Object { $_ } |
       foreach { $_ -replace " +", "," } > .\crawl.csv

非常方便的 Powershell 指南 - Powershell regular expressions

【讨论】:

  • ...欢迎对脚本进行任何更好的解决方案或改进!
  • 您可以通过去掉中间的 Foreach-Object 来简化这一点,因为 -replace 对字符串数组进行操作,例如'a b','c d','e f' -replace ' +',','。试试这个gc crawl.log -read 100 -total 100000 | %{$_ -replace ' +',','} > crawl.csv
  • 考虑到-replace,它可以更简单:(gc crawl.log ...) -replace ' +', ',' > crawl.csv(我的帖子运营商链 leporelo.eu/…)
猜你喜欢
  • 2017-03-02
  • 2021-07-24
  • 1970-01-01
  • 2013-04-04
  • 2020-12-17
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多