{"id":134,"date":"2007-05-17T20:21:21","date_gmt":"2007-05-18T04:21:21","guid":{"rendered":"http:\/\/testblog.sapien.com\/index.php\/2007\/05\/17\/powershell-just-rocks\/"},"modified":"2007-05-17T20:21:21","modified_gmt":"2007-05-18T04:21:21","slug":"powershell-just-rocks","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2007\/05\/17\/powershell-just-rocks\/","title":{"rendered":"PowerShell Just Rocks"},"content":{"rendered":"<p>I have a friend who runs a small mailing company. He has an upcoming project where he needs to send out a bunch of brochures to various people; in most cases, each envelope he sends out will contain multiple brochures &#8211; but not all will contain the same number of brochures. In other words, the postage will be different on each letter.<\/p>\n<p>So he&#8217;s already built this great CSV file containing addresses and the needed postage for each address. Problem is, the postage software he uses can&#8217;t read the postage from the file &#8211; it can only read the address. So he needed to split his one file into seperate files &#8211; one output file for each postage rate.<\/p>\n<p>His input file looks like this:<\/p>\n<p>Name,Company,Address1,Address2,City,State,ZIP,Cost,Qty<\/p>\n<p>And he needed his output file to look the same way. Doing this in VBScript isn&#8217;t a huge hassle&#8230; you read through the file, create a new output file for each rate class you encounter, and write lines out. But it&#8217;s not a super-short script, either. So I got to thinking &#8211; wouldn&#8217;t PowerShell be easier for this?<\/p>\n<p>The beauty of PowerShell, and the thing to remember, is that you almost <em>never<\/em> have to parse text &#8211; you work with <em>objects<\/em>. Check this out:<\/p>\n<pre class=\"csharpcode\">$csv = Import-Csv <span class=\"str\">&quot;input.csv&quot;<br \/><\/span>$rates = $csv | select cost -unique<br \/><span class=\"kwrd\">foreach<\/span> ($rate <span class=\"kwrd\">in<\/span> $rates) {<br \/>    $file = $rate.tostring() + <span class=\"str\">&quot;.csv&quot;<br \/><\/span>    $csv | where { $_.cost <span class=\"preproc\">-eq<\/span> $rate.cost } | Export-Csv $file<br \/>}<\/pre>\n<style type=\"text\/css\"><\/style>\n<p>All I had to do was import the CSV file using Import-CSV. This creates a collection of objects, so I can access the Cost column as a property, rather than having to split the delimited string into an array. I then select all the rate classes by using Select-Object to grab unique instances of the cost property. For each rate class, I simply pass in the input CSV data, use Where-Object to filter for rows where the cost equals the current rate class, and send that to Export-CSV. This is an easy 5-line script. And yes, I probably could have done it as a one-liner &#8211; I&#8217;m not that ambitious. The point is that working with objects beats the heck out of working with text, and PowerShell&#8217;s cmdlets &#8211; like Select-Object and Where-Object &#8211; can do some seriously heavy lifting for you if you use them properly.<\/p>\n<style type=\"text\/css\"><\/style>\n","protected":false},"excerpt":{"rendered":"<p>Here&#8217;s an excellent example of using PowerShell for string parsing and text file parsing &#8211; or, rather, NOT parsing: I have a friend who runs a small mailing company. He has an upcoming project where he needs to send out a bunch of brochures to various people; in most cases, each envelope he sends out will contain multiple brochures &#8211; but not all will contain the same number of brochures. In other words, the postage will be different on each letter.<\/p>\n<p>So he&#8217;s already built this great CSV file containing addresses and the needed postage for each address. Problem is, the postage software he uses can&#8217;t read the postage from the file &#8211; it can only read the address. So he needed to split his one file into seperate files &#8211; one output file for each postage rate&#8230;..<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[25],"tags":[],"class_list":["post-134","post","type-post","status-publish","format-standard","hentry","category-windows-powershell"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=134"}],"version-history":[{"count":0,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/134\/revisions"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}