I hate typing long command lines to command line utilities. Invariably I will get one obscure path wrong and spend an hour with a copy / pasted command line in notepad to split out the components and figure out what I screwed up this time.
A lot of those long typing jobs have to do with feeding a bunch of file or directory names to an .exe
foo_the_bar.exe --blort first\dir second\dir third\dir hey\heres\a\filename.txt
If I only had a tool that I could use to generate that list of directories and filenames.
powershell and Invoke-Expression (iex to it's friends) to the frickin' rescue.
- Write a powershell expression using Get-ChildItem (gci), Where-Object (?) and Select-Object (select) to build your list of things. Use -join ' ' to space separate the list of things
PS c:\users\kpk> (gci c:\my\dir -recurse | ?{ $_.FullName -match 'some.*criteria$' } | select -expand FullName) -join ' ' - Use string interpolation to embed that expression with the name of the .exe you want to run. In my case, I was using cloc to (duh) Count Lines Of Code.
PS c:\users\kpk> "cloc $((gci c:\my\dir -recurse | ?{ $_.FullName -match 'some.*criteria$' } | select -expand FullName) -join ' ')" - Run that expression a few times to make sure you're happy with it. Add some command line arguments as needed.
- Use iex (Invoke-Expression) to run that beautiful mess.
Let's unpack the expression a bit
PS c:\users\kpk> (gci c:\my\dir -recurse | ?{ $_.FullName -match 'some.*criteria$' } | select -expand FullName) -join ' '
- gci c:\my\dir -recurse |
gci (Get-ChildItem) recurses through a directory structure. It's more complicated than that, but things often are. - ?{ $_.FullName -match 'some.*criteria$' } |
? (Where-Object) will test each produced file & directory for a criteria. In this case, a regular expression. Only the worthy shall pass. - select -expand FullName
select (Select-Object) extracts the FullName property from the produced collection of objects and expands it to a list - -join ' '
I need that list turned into a single flattened string with space separation, because cloc wants space separation. Other command line utilities want other kind of formatting (prefixed by a magic argument, comma separated, etc.). -join's your friend here.
Never let a human do a job that a robot can do better. Ok, maybe not 'Never', but mostly. Sometimes.... Whatever.
You had me at command line.
ReplyDeleteI've been playing Admin for so long I figured command line was dead. I still use it to run my Perl scripts but it's nice to see that nuts and bolts programming is alive and well. Thanks, Kevin.
ReplyDeleteAn interesting Q&A/discussion on reddit post regarding this article...
ReplyDeletehttps://www.reddit.com/r/PowerShell/comments/mgg1ts/powershell_corruption_lies_building_command_line/gsv1sit/?context=3
seconded - I've learned a ton from this discussion.
Delete