在PowerShell中逐行处理输入[string]

时间:2018-03-01 04:21:27

标签: powershell

我正在编写一个函数,用于将IP地址列表从点分十进制形式转换为PowerShell中的无符号整数。这是我的功能:

function Convert-IPtoInteger() {

    param(
        [Parameter(Mandatory=$true, Position=0, ParameterSetName="IP Address",
            ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [string] $addresses
    )

    process {
        foreach ($ip in $addresses) {
            if ($ip -match '(\d\d?\d?\.){3}\d\d?\d?') { # approximate regex, matches some impossible addresses like 999.0.0.0
                $s = "$ip".Split(".");
                [uint32] $x = 0;
                (0..3) | ForEach-Object { # positions 0, 1, 2, 3 in previous string
                    $x = $x -shl 8; # bit shift previous value to the left by 8 bits
                    $x += $s[$_];
                }
                Write-Output $x;
            }
        }
    }
}

我曾尝试将$addresses声明为标量,并显示为[string[]]数组。在这两种情况下,管道一行多行(使用shift-enter创建)会在第一个元素之后导致错误。如果我使用Get-Content命令从文件中读取相同的文本,程序将按预期完成。

PS C:\...\1> $example = "192.168.1.1
192.168.2.1"

PS C:\...\1> $example | Convert-IPtoInteger
Cannot convert value "1
192" to type "System.UInt32". Error: "Input string was not in a correct format."
At C:\...\.ps1:16 char:18
+                     $x += $s[$_];
+                     ~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastFromStringToInteger

3232235776

PS C:\...\1> $example > example.txt

PS C:\...\1> Get-Content .\example.txt | Convert-IPtoInteger
3232235777
3232236033

我认为不同之处在于PowerShell如何处理换行。第16行($x += $s[$_])似乎在阅读" 1`n192"在同一个标​​记中,而不是从$ip语句中将每个元素作为单独的foreach接收。

Get-Member命令显示$example | Get-MemberSystem.String的实例,就像Get-Content .\example.txt | Get-Member一样。

我希望我的程序正确接受来自文本文件和字符串的输入。我在这里错过了什么?为什么Get-Content与多行字符串的解析方式不同?

1 个答案:

答案 0 :(得分:1)

将IP地址放在对象数组中:

$example = @("192.168.1.1", "192.168.2.1")
$example | convert-IPtointeger

结果:

3232235777 
3232236033

它不同的原因是因为您对字符串使用Foreach-Object:

$example1 = @("192.168.1.1", "192.168.2.1") 
$example1.GetType()

$example2 = "192.168.1.1
192.168.2.1"
$example2.GetType()

$example3 = (Get-Content "C:\Users\owain.esau\Desktop\links.txt" )
$example3.GetType()

返回以下内容

IsPublic IsSerial Name                                     BaseType                                                                                                                                                                          
-------- -------- ----                                     --------                                                                                                                                                                          
True     True     Object[]                                 System.Array                                                                                                                                                                      
True     True     String                                   System.Object                                                                                                                                                                     
True     True     Object[]                                 System.Array