Have you had a case when you had a long list of things and you wanted to split it up? Like a long shopping list which you really didn't want to tackle alone. Or you have a long list of IP addresses or host names, or object in Active Directory...whatever. And you want to split the long list to many smaller lists to run things in parallel or to stagger the running of a script (make sure you only run a script on a smaller batch at a time instead of running it on the full list).
So let's split a long list of host names to 6 pieces. You can do this in many ways, but I use this oneliner:
$NumberOfArrays = 6; $NewArrays = @{}; $i = 0; gc c:\hostlist.txt | %{$NewArrays[$i % $NumberOfArrays] += @($_); $i++}; $NewArrays
It uses a few tricks.
The first one is the modulus operator (%) which spits out the reminder part when you divide two integers. That will mean if you do a mod operation on a running number (from 1 to the max count of the list) with the number you want to split the list to, it will repeat a sequence of numbers. From 0 until it reaches the number one less than the number we are dividing by. Like this:
Lift of index numbers we can use for splitting the list |
The second trick is that this generated repeating sequence of numbers are used as index (or keys) of a hash table. Each key in the hash table has a value, in this case the values of keys will the split list of hosts. The hash table here is $NewArrays which has the arrays of the smaller lists:
The list of smaller lists (arrays) in a hash table |
Note the 'Name' column which is the list of keys.
While a nice article, using the alias % when you are trying to show others how to do something is a terrible idea.
ReplyDelete*Especially* when you also use % to mean something else in the same line.
You should really try to always write out the full command (ForEach-Object in this case) when writing something you want others to look at.