Created
June 17, 2012 11:50
-
-
Save urasandesu/2944313 to your computer and use it in GitHub Desktop.
PowerShell as LINQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ---------------------------------------------------------------------------------------------------------- | |
# PowerShell as LINQ | |
# * When I created this snippet, the blog written by NyaRuRu-san was very helpful. | |
# I would like to thank him for his article: | |
# - PowerShell で LINQ - NyaRuRuの日記: http://d.hatena.ne.jp/NyaRuRu/20080112/p2 | |
# | |
# Change History | |
# * 2012/06/20 07:23:24: Fix the bug that occurs unintended pipeline breaking. | |
# The keyword 'return' is reserved, so I use the function name 'run' instead of it. | |
# * 2012/06/23 22:26:47: Fix the bug that function 'run' doesn't stop enumeration. | |
# Add function 'flatten' that makes the list flat. | |
# Add function 'first'. It is shortcut equivalent to 'take 1'. | |
# ---------------------------------------------------------------------------------------------------------- | |
function __extract__([Collections.IEnumerator]$enum) | |
{ | |
foreach ($val in $enum) | |
{ | |
$block = $val -as [scriptblock] | |
if ($block -eq $null) | |
{ | |
throw New-Object ArgumentException('The pipeline source object must be a scriptblock.') | |
} | |
break | |
} | |
$block | |
} | |
function repeat([scriptblock]$init) | |
{ | |
{ | |
$elem = &$init | |
try | |
{ | |
while ($true) | |
{ | |
,$elem | |
} | |
} | |
finally | |
{ | |
$disp = $elem -as [IDisposable] | |
if ($disp -ne $null) | |
{ | |
$disp.Dispose() | |
} | |
} | |
}.GetNewClosure() | |
} | |
function take([int]$count) | |
{ | |
$block = __extract__ $input | |
{ | |
$count = $count | |
&$block | | |
%{ | |
if ($i++ -ge $count) | |
{ | |
break | |
} | |
,$_ | |
}.GetNewClosure() | |
}.GetNewClosure() | |
} | |
function map([scriptblock]$func) | |
{ | |
$block = __extract__ $input | |
{ | |
$func = $func | |
&$block | | |
%{ | |
,(&$func $_) | |
}.GetNewClosure() | |
}.GetNewClosure() | |
} | |
function flatten([scriptblock]$func) | |
{ | |
$block = __extract__ $input | |
{ | |
$func = $func | |
&$block | | |
%{ | |
&$func $_ | %{,$_} | |
}.GetNewClosure() | |
}.GetNewClosure() | |
} | |
function filter([scriptblock]$func) | |
{ | |
$block = __extract__ $input | |
{ | |
$func = $func | |
&$block | | |
%{ | |
if (&$func $_) | |
{ | |
,$_ | |
} | |
}.GetNewClosure() | |
}.GetNewClosure() | |
} | |
function takeWhile([scriptblock]$func) | |
{ | |
$block = __extract__ $input | |
{ | |
$func = $func | |
&$block | | |
%{ | |
if (&$func $_) | |
{ | |
,$_ | |
} | |
else | |
{ | |
break | |
} | |
}.GetNewClosure() | |
}.GetNewClosure() | |
} | |
function first | |
{ | |
__extract__ $input | take 1 | |
} | |
function run | |
{ | |
do | |
{ | |
&(__extract__ $input) | |
} until ($true) | |
} | |
# ---------------------------------------------------------------------------------------------------------- | |
# Usage | |
# ---------------------------------------------------------------------------------------------------------- | |
# dump win.ini | |
repeat {New-Object IO.StreamReader 'C:\Windows\win.ini'} | | |
map {param($_1) $_1.ReadLine()} | | |
takeWhile {param($_1) $_1 -ne $null} | | |
run | |
# the sample results are as follows: | |
# | |
# ; for 16-bit app support | |
# [fonts] | |
# [extensions] | |
# [mci extensions] | |
# [files] | |
# [Mail] | |
# MAPI=1 | |
# CMCDLLNAME32=mapi32.dll | |
# CMC=1 | |
# MAPIX=1 | |
# MAPIXVER=1.0.0.1 | |
# OLEMessaging=1 | |
# [MCI Extensions.BAK] | |
# 3g2=MPEGVideo | |
# 3gp=MPEGVideo | |
# 3gp2=MPEGVideo | |
# 3gpp=MPEGVideo | |
# aac=MPEGVideo | |
# adt=MPEGVideo | |
# adts=MPEGVideo | |
# m2t=MPEGVideo | |
# m2ts=MPEGVideo | |
# m2v=MPEGVideo | |
# m4a=MPEGVideo | |
# m4v=MPEGVideo | |
# mod=MPEGVideo | |
# mov=MPEGVideo | |
# mp4=MPEGVideo | |
# mp4v=MPEGVideo | |
# mts=MPEGVideo | |
# ts=MPEGVideo | |
# tts=MPEGVideo | |
# get 5 random numbers of one digit. | |
repeat {New-Object Random} | | |
map {param($_1) $_1.Next(0, 10)} | | |
take 5 | | |
run | |
# the sample results are as follows: | |
# | |
# 4 | |
# 8 | |
# 6 | |
# 8 | |
# 5 | |
# countdown for 10 seconds | |
$last = 0 | |
repeat {(Get-Date).AddSeconds(10.0)} | | |
map {param($_1) $_1 - (Get-Date)} | | |
takeWhile {param($_1) $_1.TotalSeconds -gt 0} | | |
run | | |
%{if ($last -ne $_.Seconds){$last = $_.Seconds; $_.Seconds}} | |
# the sample results are as follows(NOTE: each object will be displayed every second): | |
# | |
# 9 | |
# 8 | |
# 7 | |
# 6 | |
# 5 | |
# 4 | |
# 3 | |
# 2 | |
# 1 | |
# 0 | |
# enumerate each first type in each assembly from current AppDomain | |
{[AppDomain]::CurrentDomain.GetAssemblies()} | | |
flatten {param($asm) {$asm.GetTypes()} | | |
first | | |
map {param($t) $t.AssemblyQualifiedName} | | |
run} | | |
run | |
# the sample results are as follows: | |
# | |
# System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | |
# AssemblyStrings, Microsoft.PowerShell.ConsoleHost, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 | |
# FXAssembly, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | |
# System.Management.Automation.ChildItemCmdletProviderIntrinsics, System.Management.Automation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 | |
# Microsoft.PowerShell.Commands.GetWinEventCommand, Microsoft.PowerShell.Commands.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 | |
# Microsoft.Contracts.PureAttribute, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | |
# FXAssembly, System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | |
# Microsoft.WSMan.Management.WSManConfigProvider, Microsoft.WSMan.Management, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 | |
# System.Transactions.SRDescriptionAttribute, System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | |
# Microsoft.PowerShell.Commands.Internal.Format.FrontEndCommandBase, Microsoft.PowerShell.Commands.Utility, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 | |
# Microsoft.PowerShell.Commands.CoreCommandBase, Microsoft.PowerShell.Commands.Management, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 | |
# Microsoft.PowerShell.Commands.SecurityDescriptorCommandsBase, Microsoft.PowerShell.Security, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 | |
# FXAssembly, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | |
# System.Management.SRDescriptionAttribute, System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | |
# FXAssembly, System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | |
# SNINativeMethodWrapper, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | |
# FXAssembly, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | |
# System.Security.SecurityResources, System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | |
# System.Xml.Utils.ResDescriptionAttribute, System.Data.SqlXml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment