Sae*_*eed 6 sorting powershell ip-address powershell-5.1
我有一个包含一些 IP 的纯文本文件,如下所示:
194.225.0.0 - 194.225.15.255
194.225.24.0 - 194.225.31.255
62.193.0.0 - 62.193.31.255
195.146.53.128 - 195.146.53.225
217.218.0.0 - 217.219.255.255
195.146.40.0 - 195.146.40.255
85.185.240.128 - 85.185.240.159
78.39.194.0 - 78.39.194.255
78.39.193.192 - 78.39.193.207
Run Code Online (Sandbox Code Playgroud)
我想按 IP 地址对文件进行排序。我的意思是只有第一部分很重要。
我用谷歌搜索并找到了一些程序,但我想知道是否可以通过 Powershell 而不使用其他应用程序实现这一点。
我有一个像这样的 Linux 方式,但无法在 Windows 中达到它:
sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 file
Run Code Online (Sandbox Code Playgroud)
更新1
@TheMadTechnician,这是我运行你的命令时的输出:
85.185.240.128 - 85.185.240.159
195.146.40.0 - 195.146.40.255
78.39.193.192 - 78.39.193.207
78.39.194.0 - 78.39.194.255
217.218.0.0 - 217.219.255.255
194.225.24.0 - 194.225.31.255
194.225.0.0 - 194.225.15.255
195.146.53.128 - 195.146.53.225
62.193.0.0 - 62.193.31.255
Run Code Online (Sandbox Code Playgroud)
使用 RegEx-replace 的简单解决方案:为了使 IP 地址可排序,我们只需在左侧填充每个八位字节,使它们都具有相同的宽度。然后简单的字符串比较就会产生正确的结果。
对于 PS 6+:
Get-Content IpList.txt | Sort-Object {
$_ -replace '\d+', { $_.Value.PadLeft(3, '0') }
}
Run Code Online (Sandbox Code Playgroud)
对于 PS 5.x:
Get-Content IpList.txt | Sort-Object {
[regex]::Replace( $_, '\d+', { $args.Value.PadLeft(3, '0') } )
}
Run Code Online (Sandbox Code Playgroud)
-replace查找正则表达式模式的匹配项,并用给定值替换它们。-replace不支持scriptblock。使用.NETRegex.Replace方法我们可以实现同样的目的。$_表示文本文件的当前行。\d+是匹配每个 IP 地址的每个八位字节的模式。有关详细说明,请参阅regex101中的示例。{}定义输出替换值的
脚本块$_表示当前匹配(八位字节)。我们取它的值,并在左侧用零填充,因此每个八位字节总共为 3 个字符(例如,2becomes002和92becomes 092)。最终的 IP 可能如下所示194.225.024.000。使用该类的另一种解决方案Tuple。它稍微长一些,但更干净,因为它实际上比较数字而不是字符串。
Get-Content IpList.txt | Sort-Object {
# Extract the first 4 numbers from the current line
[int[]] $octets = [regex]::Matches( $_, '\d+' )[ 0..3 ].Value
# Create and output a tuple that consists of the numbers
[Tuple]::Create( $octets[0], $octets[1], $octets[2], $octets[3] )
}
Run Code Online (Sandbox Code Playgroud)
使用[regex]::Matches()我们可以找到当前行的所有数字。从返回的结果中MatchCollection我们取出前四个元素。然后我们使用成员访问枚举Value来创建每个元素的成员的字符串数组MatchCollection。
只需将字符串数组分配给具有[int[]]类型约束(s 数组int)的变量,PowerShell 就会自动将字符串解析为整数。
排序之所以有效,是因为Tuple实现了可用时使用的接口。正如预期的那样,元组按字典顺序排序。IComparableSort-Object
使用动态方法调用,我们可以[Tuple]::Create像这样缩短调用(最多适用于 8 个元素1):
[Tuple]::Create.Invoke( [object[]] $octets )
Run Code Online (Sandbox Code Playgroud)
请注意转换为[object[]],否则[Tuple]::Create将仅使用单个参数(即$octets数组)进行调用。
[1] 实际上,大于 8 个元素的元组可以通过创建嵌套元组来创建(为剩余元素创建一个元组并将其存储在基本元组的最后一个元素中)。一般来说,要执行此操作,需要递归或反向循环,首先创建大多数嵌套元组。
这个答案最初是作为我在另一个答案中的评论发布的
您可以将 IP 地址从string对象转换为对象version,该对象“恰好”与 IP 地址具有相同的格式(由 分隔的 4 组数字.)
Get-Content .\abc.txt | Sort-Object { [System.Version]($_).split("-")[1] }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2126 次 |
| 最近记录: |