简体   繁体   English

使用PowerShell以字符串格式更改第3个八位字节的IP

[英]Change 3rd octet of IP in string format using PowerShell

Think I've found the worst way to do this: 我想我找到了最糟糕的方法:

$ip = "192.168.13.1"
$a,$b,$c,$d = $ip.Split(".")
[int]$c = $c
$c = $c+1
[string]$c = $c
$newIP = $a+"."+$b+"."+$c+"."+$d

$newIP

But what is the best way? 但最好的方法是什么? Has to be string when completed. 完成后必须是字符串。 Not bothered about validating its a legit IP. 没有考虑验证其合法的IP。

Using your example for how you want to modify the third octet, I'd do it pretty much the same way, but I'd compress some of the steps together: 使用你的例子来修改你想要修改第三个八位字节的方法,我会以同样的方式完成它,但我会将一些步骤压缩在一起:

$IP = "192.168.13.1"
$octets = $IP.Split(".")                        # or $octets = $IP -split "\."
$octets[2] = [string]([int]$octets[2] + 1)      # or other manipulation of the third octet
$newIP = $octets -join "."

$newIP

You can simply use the -replace operator of PowerShell and a look ahead pattern. 您可以简单地使用PowerShell的-replace运算符和前瞻模式。 Look at this script below 请看下面的这个脚本

Set-StrictMode -Version "2.0"
$ErrorActionPreference="Stop"
cls
$ip1 = "192.168.13.123"
$tests=@("192.168.13.123" , "192.168.13.1" , "192.168.13.12")
foreach($test in $tests)
{
    $patternRegex="\d{1,3}(?=\.\d{1,3}$)"
    $newOctet="420"
    $ipNew=$test -replace $patternRegex,$newOctet
    $msg="OLD ip={0} NEW ip={1}" -f $test,$ipNew
    Write-Host $msg

}

This will produce the following: 这将产生以下结果:

OLD ip=192.168.13.123 NEW ip=192.168.420.123
OLD ip=192.168.13.1 NEW ip=192.168.420.1
OLD ip=192.168.13.12 NEW ip=192.168.420.12

How to use the -replace operator? 如何使用-replace运算符?

https://powershell.org/2013/08/regular-expressions-are-a-replaces-best-friend/ https://powershell.org/2013/08/regular-expressions-are-a-replaces-best-friend/

Understanding the pattern that I have used 理解我使用过的模式

The (?=) in \\d{1,3}(?=.\\d{1,3}$) means look behind. \\ d {1,3}(?=。\\ d {1,3} $)中的(?=)意味着落后。

The (?=.\\d{1,3}$ in \\d{1,3}(?=.\\d{1,3}$) means anything behind a DOT and 1-3 digits. (?=。\\ d {1,3} $ in \\ d {1,3}(?=。\\ d {1,3} $)表示DOT后面的任何内容和1-3位数字。

The leading \\d{1,3} is an instruction to specifically match 1-3 digits 前导\\ d {1,3}是专门匹配1-3位数的指令

All combined in plain english " Give me 1-3 digits which is behind a period and 1-3 digits located towards the right side boundary of the string " 全部用简单的英语组合“ 给我1-3个数字,这个数字落后于一个时期,1-3个数字位于字符串的右侧边界

Look ahead regex 正面看正则表达式

https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference

CORRECTION 更正

The regex pattern is a look ahead and not look behind . 正则表达式模式是前瞻性而不是落后

If you have PowerShell Core (v6.1 or higher), you can combine -replace with a script block -based replacement : 如果您有PowerShell Core (v6.1或更高版本),则可以-replace与基于脚本块的替换组合使用

PS> '192.168.13.1' -replace '(?<=^(\d+\.){2})\d+', { 1 + $_.Value }
192.168.14.1
  • Negative look-behind assertion (?<=^(\\d+\\.){2}) matches everything up to, but not including, the 3rd octet - without considering it part of the overall match to replace. 负面的后置断言(?<=^(\\d+\\.){2})匹配所有内容,但不包括第三个八位字节 - 而不考虑它是要替换的整体匹配的一部分。

    • (?<=...) is the look-behind assertion, \\d+ matches one or more ( + ) digits ( \\d ), \\. (?<=...)是后视断言, \\d+匹配一个或多个( + )数字( \\d ), \\. a literal . 文字 . , and {2} matches the preceding subexpression ( (...) ) 2 times. ,和{2}匹配前面的子表达式( (...) )2次。
  • \\d+ then matches just the 3rd octet; \\d+然后匹配第3个八位字节; since nothing more is matched, the remainder of the string ( . and the 4th octet) is left in place. 因为没有更多匹配,所以字符串( .和第4个八位字节)的其余部分保留在原位。

  • Inside the replacement script block ( { ... } ), $_ refers to the results of the match, in the form of a [MatchInfo] instance; 在替换脚本块( { ... } )内, $_[MatchInfo]实例的形式引用匹配的结果; its .Value is the matched string, ie the 3rd octet, to which 1 can be added. 它的.Value是匹配的字符串,即第3个八位字节,可以添加1

    • Data type note: by using 1 , an implicit [int] , as the LHS , the RHS (the .Value string ) is implicitly coerced to [int] (you may choose to use an explicit cast). 数据类型注意:通过使用1 ,隐式[int] ,作为LHS ,RHS( .Value 字符串 )被隐式强制转换为[int] (您可以选择使用显式转换)。
      On output, whatever the script block returns is automatically coerced back to a string . 在输出时,无论脚本块返回什么,都会自动强制转换回字符串

If you must remain compatible with Windows PowerShell , consider Jeff Zeitlin's helpful answer . 如果必须与Windows PowerShell保持兼容,请考虑Jeff Zeitlin的有用答案

For complete your method but shortly : 为了完成您的方法,但很快:

$a,$b,$c,$d = "192.168.13.1".Split(".")
$IP="$a.$b.$([int]$c+1).$d"
function Replace-3rdOctet {
    Param(
        [string]$GivenIP,
        [string]$New3rdOctet
    )
    $GivenIP -match '(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})' | Out-Null
    $Output = "$($matches[1]).$($matches[2]).$New3rdOctet.$($matches[4])"
    Return $Output
}

Copy to a ps1 file and dot source it from command line, then type 复制到ps1文件并从命令行点源,然后键入

Replace-3rdOctet -GivenIP '100.201.190.150' -New3rdOctet '42'

Output: 100.201.42.150 产量:100.201.42.150

From there you could add extra error handling etc for random input etc. 从那里你可以为随机输入等添加额外的错误处理等。

here's a slightly different method. 这是一个略有不同的方法。 [ grin ] i managed to not notice the answer by JeffZeitlin until after i finished this. [ ]直到我完成这件事之后我才注意到JeffZeitlin的答案。

[edit - thanks to JeffZeitlin for reminding me that the OP wants the final result as a string. [编辑 - 感谢JeffZeitlin提醒我OP希望最终结果为字符串。 oops! 哎呀! [*blush*]] [*脸红*]]

what it does ... 它能做什么 ...

  • splits the string on the dots 在点上分割字符串
  • puts that into an [int] array & coerces the items into that type 将它放入[int]数组并将项目强制转换为该类型
  • increments the item in the targeted slot 增加目标插槽中的项目
  • joins the items back into a string with a dot for the delimiter 将项目连接回一个带有分隔符点的字符串
  • converts that to an IP address type 将其转换为IP地址类型
  • adds a line to convert the IP address to a string 添加一行以将IP地址转换为字符串

here's the code ... 这是代码......

$OriginalIPv4 = '1.1.1.1'
$TargetOctet = 3

$OctetList = [int[]]$OriginalIPv4.Split('.')
$OctetList[$TargetOctet - 1]++

$NewIPv4 = [ipaddress]($OctetList -join '.')

$NewIPv4
'=' * 30
$NewIPv4.IPAddressToString

output ... 输出......

Address            : 16908545
AddressFamily      : InterNetwork
ScopeId            : 
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
IPAddressToString  : 1.1.2.1

==============================
1.1.2.1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM