Powershell - преобразуйте файл журнала в 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 - -
...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?

1
задан Guy 13 May 2010 в 12:12
поделиться

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 для потоковой передачи однорядных массивов в регулярное выражение
  • Затем направьте строку вывода в новый файл

ОБНОВЛЕНИЕ

Этот сценарий работает, но использует ОГРОМНЫЙ объем оперативной памяти при работе с большими файлами. Итак, как я могу сделать то же самое без использования 8 ГБ ОЗУ и подкачки!

Я думаю, это вызвано тем, что join снова буферизует все данные .... Есть идеи?

ОБНОВЛЕНИЕ 2

Хорошо, есть решение получше ...

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

ОЧЕНЬ удобное руководство по Powershell - Регулярные выражения Powershell

2
ответ дан 3 September 2019 в 00:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: