powershell - 无法从文本文件中选择的行中提取特定字段

时间:2015-02-28 01:39:16

标签: powershell

好的,所以我必须创建一个需要将协议名称作为参数传递的脚本。该脚本将在 c:\ windows \ system32 \ drivers \ etc \ protocol 文件中搜索所述协议。如果找到协议,则脚本需要返回分配给它的端口。

如果协议在该文件中,我获取整行信息(包括分配的端口)没有问题......当我需要提取端口字段时,问题出现了。

现在,我在标题中指定该行来自文本文件的原因是因为我将字段与特定行隔离没有任何问题,而这些行反过来在这些行中与一串行隔离cmdlet的输出,例如 get-process 。例如,

get-process | where-object {$_.ProcessName -eq "ServerManager"}   

将产生整行,但

 get-process | where-object {$_.ProcessName -eq "ServerManager"} | Select-Object CPU

将从该行生成特定字段。

无论如何,如果比较毫无意义或不必要,我道歉。这是脚本的代码,需要抛光/完成:

param (
[string]$protocol
)

$lines=get-content -path c:\windows\system32\drivers\etc\protocol

if ($lines -match $protocol) {

    $line=$($lines -match $protocol) 
    write-host $line #prints the entire line, port field is the second
    write-host $line.split()[0] #this prints only the first field (the protocol name)
    write-host $line.split()[1] #shouldn't this print only the second field (the assigned port)?

}

else {write-host "Protocol not found"}

好的,所以,再次,抱歉,如果我不必要地发布这个帖子...提前感谢

2 个答案:

答案 0 :(得分:1)

所以,这就是你正在使用的.Split()方法在Space字符上的分割。每个空间角色。因此,如果协议名称后面有8个空格,并且在端口之前,那么[0] = protocol,[8] = port。不太有用。对我来说什么会更好,我认为这将是一场RegEx比赛。类似的东西:

$lines=get-content -path c:\windows\system32\drivers\etc\protocol | Where {$_ -match "^$Protocol\s+?(\d+?)"} | ForEach{$Matches[1]}
If($lines.count -gt 0){
    "$Protocol protocol found using port $Lines"
}
Else{"Protocol not found"}

该匹配查找您的协议字符串,后跟任意数量的空格(空格,制表符等),然后捕获其后面的数字。 ForEach循环输出要由$ Lines捕获的数字(端口)。其余的应该很容易遵循。

编辑:要扩展它为什么不像Get-Process示例那样工作,因为cmdlet Get-Process返回一组对象和那些对象有几个属性,如CPU,PID,路径等。您可以选择其中一个属性来显示。文本文件中的行只是字符串。字符串是对象,当然,但它们只有一个功能属性,而且它们是存储在其中的文本(是的,它们有方法,但我们只是在谈论可以存储值的属性)。因此,没有像运行Get-Process时那样选择属性。我希望这有助于明确这一点。

Edit2:好的,如果我们想要避免RegEx(您应该完全阅读并了解您是否计划进行任何解析或字符串操作),我们可以使用split still。勉强,但它可以做到。我甚至可以像马特的例子那样制作漂亮的小物件,因为它们更容易使用,而且更好,我之前只是懒惰而且马特是对的。

$Lines = Get-Content c:\windows\system32\drivers\etc\protocol |Where{$_ -notlike "#*" -and !([string]::IsNullOrEmpty($_))}
$Protocols = ForEach($Line in $Lines){
    $SplitLine = $Line.split()|Where{!([String]::IsNullOrEmpty($_))}
    [PSCustomObject][Ordered]@{
        'ProtocolName' = $SplitLine[0]
        'Port' = $SplitLine[1]
        'Aliases' = $SplitLine[2]
        'Comment' = $SplitLine[4..($SplitLine.count)] -join " "
    }
}

现在$ Protocols将输出如下内容:

PS C:\Windows\System32\WindowsPowerShell\v1.0> $Protocols

ProtocolName                                          Port                                                  Aliases                                              Comment                                             
------------                                          ----                                                  -------                                              -------                                             
ip                                                    0                                                     IP                                                   Internet protocol                                   
icmp                                                  1                                                     ICMP                                                 Internet control message protocol                   
ggp                                                   3                                                     GGP                                                  Gateway-gateway protocol                            
tcp                                                   6                                                     TCP                                                  Transmission control protocol                       
egp                                                   8                                                     EGP                                                  Exterior gateway protocol                           
pup                                                   12                                                    PUP                                                  PARC universal packet protocol                      
udp                                                   17                                                    UDP                                                  User datagram protocol                              
hmp                                                   20                                                    HMP                                                  Host monitoring protocol                            
xns-idp                                               22                                                    XNS-IDP                                              Xerox NS IDP                                        
rdp                                                   27                                                    RDP                                                  "reliable datagram" protocol                        
ipv6                                                  41                                                    IPv6                                                 Internet protocol IPv6                              
ipv6-route                                            43                                                    IPv6-Route                                           Routing header for IPv6                             
ipv6-frag                                             44                                                    IPv6-Frag                                            Fragment header for IPv6                            
esp                                                   50                                                    ESP                                                  Encapsulating security payload                      
ah                                                    51                                                    AH                                                   Authentication header                               
ipv6-icmp                                             58                                                    IPv6-ICMP                                            ICMP for IPv6                                       
ipv6-nonxt                                            59                                                    IPv6-NoNxt                                           No next header for IPv6                             
ipv6-opts                                             60                                                    IPv6-Opts                                            Destination options for IPv6                        
rvd                                                   66                                                    RVD                                                  MIT remote virtual disk    

你可以根据需要过滤它,比如Matt所描述的,比如

$Protocols | Where{$_.ProtocolName -ieq $Protocol}

答案 1 :(得分:1)

赞美TheMadTechnicians的回答。这应该将文本文件转换为您可以引用的对象,如其他cmdlet的输出。

$protocols = get-content -path c:\windows\system32\drivers\etc\protocol | Where-Object{$_ -and ($_ -notmatch "^#")} | ForEach-Object{
    $protocol = $_ -split '\s+'
    [pscustomobject]@{
        ProtocolName = $protocol[0]
        Port = $protocol[1]
        Alias = $protocol[2]
        Comment = $protocol[4..$($protocol.Count)] -join " "
    }
}

然后你可以做这样的事情

$protocols | Where-Object{$_.ProtocolName -eq "udp"}

哪会净回报

ProtocolName Port Alias Comment               
------------ ---- ----- -------               
udp          17   UDP   User datagram protocol