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

时间:2019-02-27 16:37:00

标签: regex string powershell concatenation

认为我已经找到了最糟糕的方法:

$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

但是最好的方法是什么?完成时必须为字符串。不必为验证其合法IP而烦恼。

6 个答案:

答案 0 :(得分:3)

使用有关如何修改第三个八位位组的示例,我将以几乎相同的方式进行操作,但是我将一些步骤压缩在一起:

$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

答案 1 :(得分:1)

您可以简单地使用PowerShell的 -replace 运算符和前瞻模式。在下面看这个脚本

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

}

这将产生以下内容:

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

如何使用-replace运算符?

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

了解我使用的模式

\ d {1,3}(?=。\ d {1,3} $)中的(?=)表示向后看。

\ d {1,3}中的(?=。\ d {1,3} $((?=。\ d {1,3} $))表示DOT和1-3位数字之后的任何数字。

前导\ d {1,3}是专门匹配1-3位数字的指令

全部用普通英语组合成一个字母“ 给我1-3个数字,该数字在句点后面,而1-3个数字位于字符串的右侧边界

正则表达式

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

更正

正则表达式模式是向前看,而不是向后看

答案 2 :(得分:1)

如果您具有 PowerShell Core (v6.1或更高版本),则可以-replace script块组合的替换

PS> '192.168.13.1' -replace '(?<=^(\d+\.){2})\d+', { 1 + $_.Value }
192.168.14.1
  • 负向后断言(?<=^(\d+\.){2})匹配(但不包括)第三个八位位组的所有内容-而不考虑将其替换为整个匹配的一部分。

    • (?<=...)是一种后置断言,\d+匹配一个或多个(+)位数字(\d),\.是一个文字 .{2}匹配前面的子表达式((...))2次。
  • \d+然后仅匹配第三个八位位组;由于没有其他匹配项,因此字符串的其余部分(.和第四个八位字节)保留在原处。

  • 在替换脚本块({ ... }中,$_[MatchInfo]实例的形式引用匹配的结果;其.Value是匹配的字符串,即可以添加1的第三个八位字节。

    • 数据类型注释:通过使用1(隐式[int])作为Rem(Lem)(.Value 字符串 LHS >)被隐式强制为[int](您可以选择使用显式强制转换)。
      在输出时,脚本块返回的所有内容都会自动强制返回到 string

如果您必须与 Windows PowerShell 保持兼容,请考虑使用Jeff Zeitlin's helpful answer

答案 3 :(得分:1)

为完成您的方法,但不久之后:

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

答案 4 :(得分:0)

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
}

复制到ps1文件,然后从命令行对其进行点源,然后键入

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

输出:100.201.42.150

从那里可以为随机输入等添加额外的错误处理等。

答案 5 :(得分:0)

这是稍微不同的方法。 [咧嘴]我设法直到完成后才注意到JeffZeitlin的回答。

[edit-感谢JeffZeitlin提醒我,OP希望最终结果为字符串。哎呀! [*脸红*]]

它做什么...

  • 将字符串分割成点
  • 将其放入[int]数组并将其强制转换为该类型
  • 增加目标位置中的项目
  • 将项目重新连接到带点分隔符的字符串中
  • 将其转换为IP地址类型
  • 添加一行以将IP地址转换为字符串

这是代码...

$OriginalIPv4 = '1.1.1.1'
$TargetOctet = 3

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

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

$NewIPv4
'=' * 30
$NewIPv4.IPAddressToString

输出...

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

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