Бег на 110 метров с барьерами.
Задача:
Решение:
Всё копировать не буду, а только приведу уже готовый скрипт. Сам текст скрипта можно взять тут: Hey, Scripting Guy! Opening Ceremonies and 2009 Scripting Games Event 6 Details (Beginner and Advanced; 110-meter hurdles). Исходные ошибочные строки привёл в комментарии:
#========================================================================== # # PowerShell: AUTHOR: Ed Wilson , msft, 6/15/2009 # # NAME: Beg_6.ps1 # # COMMENT: Key concepts are listed below: #1. Uses wscript.shell to create three shortcuts on the desktop. The first is a shortcut #2. to this actual script. It uses the scriptfullName property to assign the path. #3. The second is a simple Web site URL shortcut. The third one is a shortcut to #4. Notepad. #========================================================================== $ErrorActionPreference = "SilentlyContinue" Set-PSDebug -Strict New-Variable -Name objShell #instance of the wshSHell object New-Variable -Name strDesktop #pointer to desktop special folder New-Variable -Name objShortCut #used to set properties of the shortcut. Comes from using createShortCut New-Variable -Name objURL #used to set properties of webshortcut. # было: $oShell = New-Object -ComObject ("WScript.Shell") - ошибка в имени переменной $objShell = New-Object -ComObject ("WScript.Shell") $strDesktop = $objShell.SpecialFolders.item("Desktop") $objShortCut = $objShell.CreateShortcut($strDesktop + "\Shortcut Script.lnk") # было: $objShortCut.TargetPath = $MyInvocation.ScriptName - неверное свойство $objShortCut.TargetPath = $MyInvocation.MyCommand $objShortCut.WindowStyle = 0 $objShortCut.Hotkey = "CTRL+SHIFT+F" $objShortCut.IconLocation = "notepad.exe, 2" $objShortCut.Description = "Shortcut Script" $objShortCut.WorkingDirectory = $strDesktop # было: $objShortCut.Save - при вызове метода забыли скобки $objShortCut.Save() # $wshShell = New-Object -ComObject wscript.shell - не нужно совсем # было: $objURL = $objShell.CreateShortcut($strDesktop & "\The Microsoft Scripting Guys.url") # вместо + поставили & из VBS $objURL = $objShell.CreateShortcut($strDesktop + "\The Microsoft Scripting Guys.url") $objURL.TargetPath = "http://www.ScriptingGuys.com" # было: $objURL.Discription = "Scripting Guys". Такого свойства в URL файлах нету. $objURL.Save() # было: $wshNetwork = New-Object -ComObject wscript.network - не нужно свсем # было: $objShortCut = $objShell.CreateShortcut($strDesktop + "\notepad.link") # расширение не LNK, а LINK $objShortCut = $objShell.CreateShortcut($strDesktop + "\notepad.lnk") # было: $objShortCut.TargetPath = "notpad.exe" - пропустили букву E $objShortCut.TargetPath = "notepad.exe" $objShortCut.IconLocation = "notepad.exe, 0" $objShortCut.description = "notepad" $objShortCut.Save()
Если запустить этот скрипт из файла, то получится 3 ярлыка и первый будет вести именно на файл самого скрипта.
и снова задача на парсинг текста. Потребуется файл network trace_adv6.txt из Competitors pack.
Задача:
Решение:
Самая первая задача, которая перед нами встаёт – создание регулярного выражения. Выражение у меня получилось вот такое:
^\d+\W+(\d+)\D+(\d+)\D+(\d+) ms (.*)
Что оно делает: оно откидывает порядковый номер прыжка (hop), любую небуквенную последовательность (в общем смысле [A-Za-z0-9]) и выбирает первую последовательность чисел. Эта последовательность будет будет являться временем первой попытки посылки ICMP пакета. Далее откидывается любая нечисловая последовательность и выбирается первая же числовая последовательность, которая будет являться второй попыткой посылки ICMP пакета. То же самое делаем до 3-й попытки текущего прыжка включительно. После выкидываем пробел и последовательность букв “ms”, за ней 2 пробела и захватываем всё до конца строки, что будет являеться адресом и/или именем маршрутизатора. Т.к. перед порядковыми номерами прыжков (до 9 включительно) присуствует пробел, то его можно средать методом Trim() и уже подставлять выражение. Из захваченного времени нужно на лету посчитать среднее значение. И вот что у меня вышло:
[↓] [vPodans] gc "Network Trace_Adv6.txt" | ?{$_.trim() -match "^\d+\W+(\d+)\D+(\d+)\D+(\d+) ms (.*)"} | %{ >> $current = "" | Select @{n='Average';e={[int](([int]$matches[1]+[int]$matches[2]+[int]$matches[3])/3)}}, >> @{n='Name';e={$matches[4]}} >> $current >> } | ft -a >> Average Name ------- ---- 1 r10.ntwk.nwtraders.com [192.168.227.82] 1 r20.ntwk.nwtraders.com [192.168.169.1] 1 r50.ntwk.nwtraders.com [192.226.42.47] 13 r70.ntwk.nwtraders.com [192.226.42.12] 34 r12.ntwk.nwtraders.com [192.226.42.9] 34 r40.ntwk.nwtraders.com [192.226.42.22] 104 r22.ntwk.nwtraders.com [192.226.34.80] 105 r32.ntwk.nwtraders.com [192.226.47.10] 125 r35.ntwk.nwtraders.com [192.226.41.198] 173 r37.ntwk.nwtraders.com [192.226.38.14] 173 r38.ntwk.nwtraders.com [192.226.226.119] 389 192.168.216.5 390 r60.ntwk.nwtraders.com [192.168.236.9] [↓] [vPodans]
Теперь нужно определить на каких участках происходит замедление. Я решил поэтапно циклом For проверять каждый элемент массива – меньше ли он, чем следующий элемент или нет. Если он равен или больше следующего элемента, то ничего делать не надо, т.к. замедления нету. Если меньше, то он является пограничным этапом, где происходит замедление и выводим его на экран. Привожу уже готовый код и полученный результат:
$sum = @() gc "Network Trace_Adv6.txt" | ?{$_.trim() -match "^\d+\W+(\d+)\D+(\d+)\D+(\d+) ms (.*)"} | %{ $current = "" | Select @{n='Average';e={[int](([int]$matches[1]+[int]$matches[2]+[int]$matches[3])/3)}}, @{n='Name';e={$matches[4]}} $sum += $current } $(for ($i = 0; $i -le $sum.Count; $i++ ) { if ($sum[$i].Average -lt $sum[$i + 1].Average) {$sum[$i]} if ($i -eq ($sum.Count - 1)) {$sum[$i]} }) | ft @{l='Average';e={$_.Average};a='left'}, @{l='Name';e={$_.name}} -AutoSize
[↓] [vPodans] $sum = @() [↓] [vPodans] gc "Network Trace_Adv6.txt" | ?{$_.trim() -match "^\d+\W+(\d+)\D+(\d+)\D+(\d+) ms (.*)"} | %{ >> $current = "" | Select @{n='Average';e={[int](([int]$matches[1]+[int]$matches[2]+[int]$matches[3])/3)}}, >> @{n='Name';e={$matches[4]}} >> $sum += $current >> } >> $(for ($i = 0; $i -le $sum.Count; $i++ ) { >> if ($sum[$i].Average -lt $sum[$i + 1].Average) {$sum[$i]} >> if ($i -eq ($sum.Count - 1)) {$sum[$i]} >> }) | ft @{l='Average';e={$_.Average};a='left'}, @{l='Name';e={$_.name}} -AutoSize >> Average Name ------- ---- 1 r50.ntwk.nwtraders.com [192.226.42.47] 13 r70.ntwk.nwtraders.com [192.226.42.12] 34 r40.ntwk.nwtraders.com [192.226.42.22] 104 r22.ntwk.nwtraders.com [192.226.34.80] 105 r32.ntwk.nwtraders.com [192.226.47.10] 125 r35.ntwk.nwtraders.com [192.226.41.198] 173 r38.ntwk.nwtraders.com [192.226.226.119] 389 192.168.216.5 390 r60.ntwk.nwtraders.com [192.168.236.9] [↓] [vPodans]
А теперь обратите внимание на одну вещь, о которой не все знают:
ft @{l='Average';e={$_.Average};a='left'}
при форматировании Format-Table вы можете атрибутум A (от слова align) двигать содержимое колонки относительно названия. В первом примере у меня стандартное форматирование и выравнивание Avarage по правому краю. Здесь же я содержимое выравнил по левому краю, чтобы не сливались цифры. Хотя это решается удалением –AutoSize, но мне нравится этот ключ :-) вобщем, об этой фиче не забывайте.
Comments: