Powershell и объектный pipe
Я задумался над тем, чтобы показать как могла бы выглядеть обработка логов на PowerShell. Как я уже говорил, pipe в PowerShell объектный, то есть по нему идёт не монолитный текст, а набор объектов. Вот я и попробую на примере показать что это.
Для начала настроим лог Apache так, чтобы его было удобнее парсить. К примеру, можно ввести символы табуляций — в логе они не встречаются и вполне подходят на роль разделителя:
LogFormat "%h\t%l\t%u\t%t\t\"%r\"\t%>s\t%b" common
CustomLog logs/access.log commonВ логе у нас есть: хост клиента, его ident, имя пользователя (если была произведена
127.0.0.1 - - [03/Jan/2010:16:35:30 +0300] "GET /favicon.ico HTTP/1.1" 404 1976
127.0.0.1 - - [03/Jan/2010:16:35:32 +0300] "GET /a.html HTTP/1.1" 200 521
127.0.0.1 - - [03/Jan/2010:16:35:33 +0300] "GET /favicon.ico HTTP/1.1" 404 1976Предположим, наша задача — разобрать лог, отобрать только те запросы, у которых код ответа 200, отсортировать по размеру контента и вывести в табличном виде название метода, URL и размер контента.
cat access.log | %`
{
$o = "" | Select-Object host, logname, user, date, url, code, len, method
$o.host, $o.logname, $o.user, $o.date, $o.url, $o.code, $o.len = $_.Split("`t")
[datetime]$o.date = $o.date -replace '^.([^:]+):(.+).$', '$1 $2'
"logname", "user", "len" | %{ If ($o.$_ -eq '-') { $o.$_ = $false } }
$o.method, $o.url = $o.url.SubString(1).Split()[0..1]
$o
} | ?{ $_.code -eq 200 } | Sort-Object -property len | Format-Table method, url, lenИтак, что здесь происходит. Читаем лог, проходимся по каждой его строке (%{ }), внутри цикла странным хаком
Последней строкой цикла выводим получившийся объект. До цикла по pipe шли объекты попроще — всего лишь наборы строк («System.String»), теперь идут более интересные объекты («System.Management.Automation.PSCustomObject» с заданными нами полями).
Из этих объектов мы вибираем только те, у которых поле «code» содержит значение 200 («?{}» — это короткий алиас
method url len
------ --- ---
GET / 4701
GET / 4701
GET / 4701
GET / 4701
GET /a.html 521
GET /a.html 521Надо будет после праздников взглянуть на PowerShell 2.0, говорят, там очень много нового и интересного добавили.