2009-10-20 51 views
1

我经常想处理导致修改后的输出文件的文件。我似乎无法找到PowerShell的方式做到这一点 - 它总是结束了在一衬垫,IYSWIM看起来像代码。这是一个例子。PowerShell查询:如何处理文件

我有一个LMHOSTS文件。不要问为什么!我想获得一个只包含响应ping的服务器的新LMHOSTS文件。我也想通过任何评论线。

评论行以#开头。

数据线这样的事情(用空格隔开):

10.123.177.1 SVRDS1 #PRE #DOM:DOM1 

或本:

10.241.177.30 SVRDS30 #PRE 

这是我有什么(与感谢Luke与刘炳章帮助主机):

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 } } } 

它的工作原理,但它不是很好。我采取了程序员的方法,但是将其作为一行代码来完成。有没有更好的方式来做到这一点,这是更'壳'和更少'代码'?

+2

小心使用类似。我会使用-match'^ \ s *#'来代替。如果有一个初始空间,类似的语句将无法捕捉它。 – 2009-10-20 17:26:34

+0

感谢您的发现。 – serialhobbyist 2009-10-21 17:44:09

回答

3

在此特定示例中,您正在过滤1个文件的内容并将其输出到另一个文件。 Where-Object通常是一个很好的选择。然后,您可以简化您的一行位:

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

一些注意事项: “?”

  • 是Where-Object的别名
  • -or运算符会短路,即如果第一个操作数导致True,则第二个操作符不会执行。
  • 您可以使用重定向运算符“>”代替“| Out-File”。
  • 我用Split取代了Substring,它看起来稍微简单一些,不确定是否与你的输入一般工作。
+1

我喜欢这种方法。如果你使用PowerShell 2.0,我只需用Test-Connection -quiet替换Ping-Host的用法。顺便说一句,如果你想保持原始编码,我会退回到Out-File -enc ascii。 – 2009-10-20 17:31:41

+0

噢,大概的样,因为我对这个问题帖子中提到的脆性与-match相同意见。 – 2009-10-20 17:32:22

+0

啊,是的。这看起来比我的好。非常感谢。 – serialhobbyist 2009-10-21 17:49:12

1

空白是你的朋友!在Powershell脚本中,我写的并不是立即抛出,几乎每个'|'之后是换行符+缩进。

+1

啊,但那不会是单线。 :-) – serialhobbyist 2009-10-20 16:04:37

+0

好吧,我想我误解了什么样的“风格”你希望能改进。 – 2009-10-20 17:41:43