![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | Skeleton for file processing scripts Hi, I often need a script that operates on files. While it isn't that hard to write such a script, writing it the right way can be a tedious task. By "right way" I mean that the script should support a path and literalPath parameter as well as pipline input. It should support globbing and the ability to bind to an objects path property. So here's what the skeleton currently looks like: # Process-File.ps1 param( [object]$path, [string]$literalPath ) begin { function ProcessFile([IO.FileInfo]$file) { # actual implementation goes here $file } function ProcessInput($i) { if(! $i){return} if($i -is [IO.FileInfo]) { ProcessFile $i } elseif($i -is [IO.DirectoryInfo]) { # skip directories } elseif($i.Path) { # Bind to the objects Path property ProcessFile ([IO.FileInfo]$i.Path) } else { # support for globbing foreach($pi in (resolve-path $i)) { ProcessFile ([IO.FileInfo]$pi.Path) } } } } process { ProcessInput $_ } end { ProcessInput $path if($literalPath) { ProcessInput ([IO.FileInfo]$literalPath) } } #eof By using this script as a starting point you only have to implement the ProcessFile function. After doing so you can then use your script in the following ways: # Binds directly to the FileInfo object PS> ls | .\Process-File.ps1 # Binds to the Path property of Process PS> gps | .\Process-File.ps1 # Support for globbing PS> .\Process-File.ps1 *.txt # Support for an array of paths+globbing PS> .\Process-File.ps1 *.txt,*.ps1 # Support for literalPath PS> .\Process-File.ps1 -literalPath "[a-z].txt" Did I miss something? Any comments? cu Max |
My System Specs![]() |
| | #2 (permalink) |
| | Re: Skeleton for file processing scripts That looks great. The script does a good job of handling some of the C# cmdlet features that we want to eventually add to scripts in a more first-class manner. One thing that might cause confusion for readers of the script is the way that it closely intertwines pipeline-oriented input with parameter-based input. The script uses the pipeline control structures (begin, process, and end,) but acts like a non-pipeline script for much of the rest. An alternative approach you might consider is to explicitly foreach over $input, as it might make your script easier to understand. -- Lee Holmes [MSFT] Windows PowerShell Development Microsoft Corporation This posting is provided "AS IS" with no warranties, and confers no rights. "Maximilian Hänel" <ngSpam@smjh.de> wrote in message news:uwdJ0cTMHHA.5104@TK2MSFTNGP06.phx.gbl... > Hi, > > I often need a script that operates on files. While it isn't that hard to > write such a script, writing it the right way can be a tedious task. By > "right way" I mean that the script should support a path and literalPath > parameter as well as pipline input. It should support globbing and the > ability to bind to an objects path property. So here's what the skeleton > currently looks like: > > # Process-File.ps1 > param( > [object]$path, > [string]$literalPath > ) > begin > { > function ProcessFile([IO.FileInfo]$file) > { > # actual implementation goes here > $file > } > function ProcessInput($i) > { > if(! $i){return} > > if($i -is [IO.FileInfo]) > { > ProcessFile $i > } > elseif($i -is [IO.DirectoryInfo]) > { > # skip directories > } > elseif($i.Path) > { > # Bind to the objects Path property > ProcessFile ([IO.FileInfo]$i.Path) > } > else > { > # support for globbing > foreach($pi in (resolve-path $i)) > { > ProcessFile ([IO.FileInfo]$pi.Path) > } > } > } > } > process > { > ProcessInput $_ > } > end > { > ProcessInput $path > if($literalPath) > { > ProcessInput ([IO.FileInfo]$literalPath) > } > } > #eof > > By using this script as a starting point you only have to implement the > ProcessFile function. After doing so you can then use your script in the > following ways: > > # Binds directly to the FileInfo object > PS> ls | .\Process-File.ps1 > > # Binds to the Path property of Process > PS> gps | .\Process-File.ps1 > > # Support for globbing > PS> .\Process-File.ps1 *.txt > > # Support for an array of paths+globbing > PS> .\Process-File.ps1 *.txt,*.ps1 > > # Support for literalPath > PS> .\Process-File.ps1 -literalPath "[a-z].txt" > > Did I miss something? Any comments? > > cu > > Max |
My System Specs![]() |
| | #3 (permalink) |
| | Re: Skeleton for file processing scripts Hi Lee, > That looks great. Thanks for feedback! > The script does a good job of handling some of the C# > cmdlet features that we want to eventually add to scripts in a more > first-class manner. Nice! Do you have a PowerShell "roadmap"? I'm curious when we can expect the next release ;-) > One thing that might cause confusion for readers of the script is the way > that it closely intertwines pipeline-oriented input with parameter-based > input. The script uses the pipeline control structures (begin, process, and > end,) but acts like a non-pipeline script for much of the rest. > > An alternative approach you might consider is to explicitly foreach over > $input, as it might make your script easier to understand. Hmm, sounds interesting. Let me see if I understood you right: param( [object]$path, [string]$literalPath ) function ProcessFile([IO.FileInfo]$file) { # TODO: implement ProcessFile $file } function ProcessInput($i) { if($i -is [IO.FileInfo]) { ProcessFile $i } elseif($i -is [IO.DirectoryInfo]) { # always skip directories } elseif($i.Path) { # Bind to the objects Path property ProcessFile ([IO.FileInfo]$i.Path) } else { # support for globbing foreach($pi in (resolve-path $i)) { ProcessFile ([IO.FileInfo]$pi.Path) } } } # process pipline input if present if($input) { foreach($pi in $input){ProcessInput $pi} } # process path argument if present if($path) { ProcessInput $path } # process $literalPath argument if present if($literalPath) { ProcessInput ([IO.FileInfo]$literalPath) } #eof cu Max |
My System Specs![]() |
| | #4 (permalink) |
| | Re: Skeleton for file processing scripts That's exactly what I meant ![]() As for the roadmap, our next big goal is to provide you guys with remoting support. Speculation past that would be a little premature right now. -- Lee Holmes [MSFT] Windows PowerShell Development Microsoft Corporation This posting is provided "AS IS" with no warranties, and confers no rights. "Maximilian Hänel" <ngSpam@smjh.de> wrote in message news:uvnPCpDNHHA.536@TK2MSFTNGP02.phx.gbl... > Hi Lee, > >> That looks great. > > Thanks for feedback! > >> The script does a good job of handling some of the C# cmdlet features >> that we want to eventually add to scripts in a more first-class manner. > > Nice! Do you have a PowerShell "roadmap"? I'm curious when we can expect > the next release ;-) > >> One thing that might cause confusion for readers of the script is the way >> that it closely intertwines pipeline-oriented input with parameter-based >> input. The script uses the pipeline control structures (begin, process, >> and end,) but acts like a non-pipeline script for much of the rest. >> >> An alternative approach you might consider is to explicitly foreach over >> $input, as it might make your script easier to understand. > > Hmm, sounds interesting. Let me see if I understood you right: > > param( > [object]$path, > [string]$literalPath > ) > > function ProcessFile([IO.FileInfo]$file) > { > # TODO: implement ProcessFile > $file > } > > function ProcessInput($i) > { > if($i -is [IO.FileInfo]) > { > ProcessFile $i > } > elseif($i -is [IO.DirectoryInfo]) > { > # always skip directories > } > elseif($i.Path) > { > # Bind to the objects Path property > ProcessFile ([IO.FileInfo]$i.Path) > } > else > { > # support for globbing > foreach($pi in (resolve-path $i)) > { > ProcessFile ([IO.FileInfo]$pi.Path) > } > } > } > > # process pipline input if present > if($input) > { > foreach($pi in $input){ProcessInput $pi} > } > > # process path argument if present > if($path) > { > ProcessInput $path > } > > # process $literalPath argument if present > if($literalPath) > { > ProcessInput ([IO.FileInfo]$literalPath) > } > #eof > > cu > > Max |
My System Specs![]() |
| | #5 (permalink) |
| | Re: Skeleton for file processing scripts Hi Lee, > That's exactly what I meant ![]() :-) > As for the roadmap, our next big goal is to provide you guys with remoting > support. Cool! > Speculation past that would be a little premature right now. That's too bad... ;-) Thanks again, Max |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| Running file iteration and other scripts under Vista security. How | VB Script | |||
| Log In Out File Processing | PowerShell | |||
| XML processing my web.config file in PowerShell | PowerShell | |||
| Clear-Content Cmdlet and Processing Lines in Text File | PowerShell | |||
| Script for automatically generating a .NET object-centered cmdlet skeleton | PowerShell | |||