开发者

PowerShell query: how to process a file

I often开发者_Go百科 want to process a file resulting in a modified output file. I can't seem to find the PowerShell way to do this - it always ends up looking like code in a one-liner, IYSWIM. This is an example.

I have an LMHOSTS file. Don't ask why! I want to get a new LMHOSTS file that only contains servers that respond to pings. I also want to pass through any comment lines.

Comment lines begin with a #.

Data lines are something like this (space-separated):

10.123.177.1    SVRDS1 #PRE #DOM:DOM1

or this:

10.241.177.30   SVRDS30 #PRE

This is what I've got (with thanks to Luke for help with Ping-Host):

gc 'C:\work\lmhosts.txt' | % { if ($_ -like '#*') { $_ | out-file 'C:\work\lmhosts2.txt' -append } else { if ($(Ping-Host $_.Substring(0, $_.indexof(' ')) -count 1 -timeout 10).received -eq 1) { $_ | out-file 'C:\work\lmhosts2.txt' -append } } }

It works but it's not nice. I've taken a programmer's approach but done it as a one-liner. Is there a better way of doing it, that's more 'shell' and less 'code'?


In this particular example, you are filtering the contents of 1 file and outputting it to another. Where-Object is usually a good choice for this. You can then simplify your one-liner a bit:

gc 'C:\work\lmhosts.txt' | 
    ?{ ($_ -like '#*') -or 
       ($(Ping-Host $_.Split(' ')[0]) -count 1 -timeout 10).received -eq 1) } > 
    'C:\work\lmhosts2.txt'

Some notes:

  • "?" is an alias for Where-Object
  • The -or operator will short circuit, that is, if the first operand results in True, the second will not bother executing.
  • You can use the redirection operator ">" instead of "| Out-File".
  • I replaced Substring with Split, it seemed slightly simpler, not sure if works in general with your input.


Whitespace is your friend! In Powershell scripts I write that aren't immediately thrown away, almost every '|' is followed by a newline + indent.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜