[PowerShell 入门教程]第6天课后作业的完整答案与详细解析

📅 第6天重点总结回顾

技术点用途最佳实践
Select-String高效文本/日志搜索用 -Pattern + -Context 查看前后行
正则表达式模式匹配与提取优先用 [regex]::Matches() 获取所有匹配组
-Tail / -Raw控制大文件内存占用日志分析首选 -Tail 100 避免加载全文件
$_ 与计算属性自定义输出结构Select-Object @{Name="X"; Expression={...}}
.Where() 方法本地数组高性能过滤比 Where-Object 快 5–10 倍(无管道开销)

🏁 课后作业答案与解析


作业1:从 setupact.log 提取驱动包名称

💡 路径:C:\Windows\setupact.log(Windows 安装/更新日志,通常存在)

✅ 脚本:Get-DriverPackages.ps1
# 检查日志是否存在
$logPath = "C:\Windows\setupact.log"
if (-not (Test-Path $logPath)) {
    Write-Warning "日志文件不存在: $logPath"
    return
}

# 使用 Select-String 搜索包含 "Installing driver package:" 的行
# 并通过正则提取驱动包名(XXX 部分)
$pattern = 'Installing driver package:\s*(.+)'

# 为节省内存,仅读取最后 500 行(假设驱动安装在近期)
$matches = Get-Content -Path "C:\Windows\setupact.log" -Tail 500 |
           Select-String -Pattern 'Installing driver package:\s*(.+)'

# 提取捕获组(即驱动包名称),去重并排序
$driverPackages = $matches |
    ForEach-Object { $_.Matches.Groups[1].Value } |
    Sort-Object -Unique

if ($driverPackages) {
    Write-Host "找到 $($driverPackages.Count) 个唯一驱动包:" -ForegroundColor Green
    $driverPackages
} else {
    Write-Host "未找到驱动安装记录。" -ForegroundColor Yellow
}
🔍 关键解析:
  •  流式处理(避免一次性加载所有 500 行到内存)

Get-Content -Path "C:\Windows\setupact.log" -Tail 500 |
           Select-String -Pattern 'Installing driver package:\s*(.+)' 

  • 正则 (.+):捕获 Installing driver package: 后的所有内容
  • $_.Matches.Groups[1].Value:访问第一个捕获组(即 XXX)
  • Sort-Object -Unique:自动去重并排序

✅ 示例输出:

oem123.inf
usbccgp.inf
wudfusb.inf

作业2:从文本中提取所有邮箱地址并去重

✅ 脚本:Extract-Emails.ps1
# 模拟一段含邮箱的文本(可替换为 Get-Content 读文件)
$text = @"
Contact us at support@example.com or sales@contoso.org.
Also reach out to admin@local, user.name+tag@domain.co.uk, and invalid-email.
For help: help@sub.domain.com
"@

# 使用 [regex]::Matches() 提取所有符合邮箱格式的字符串
$emailRegex = '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'

$allMatches = [regex]::Matches($text, $emailRegex)

# 提取值、转小写(标准化)、去重
$uniqueEmails = $allMatches.Value |
    ForEach-Object { $_.ToLower() } |
    Sort-Object -Unique

Write-Host "提取到 $($uniqueEmails.Count) 个唯一邮箱:" -ForegroundColor Cyan
$uniqueEmails
🔍 关键解析:
  • [regex]::Matches():返回所有匹配对象(比 -match 更适合多结果)
  • 正则说明
    • [a-zA-Z0-9._%+-]+:用户名部分(允许常见符号)
    • @:必须有 @
    • [a-zA-Z0-9.-]+:域名(允许子域和连字符)
    • \.[a-zA-Z]{2,}:顶级域(至少2字母)
  • .ToLower():避免 User@Example.COM 和 user@example.com 被视为不同

✅ 输出:

help@sub.domain.com
sales@contoso.org
support@example.com
user.name+tag@domain.co.uk

⚠️ 注意:此正则不完美,但适用于大多数日志场景。如需严格校验,可集成 .NET 的 MailAddress 类。


作业3:对比 Where-Object 与 .Where() 性能

✅ 脚本:Compare-FilterPerformance.ps1
# 模拟 10,000 个进程对象(避免真实 Get-Process 开销)
$processes = 1..10000 | ForEach-Object {
    [PSCustomObject]@{
        Name = "Process$_"
        Id   = Get-Random -Minimum 1000 -Maximum 99999
        CPU  = Get-Random -Minimum 0 -Maximum 100
    }
}

# 方法1:使用 Where-Object(管道)
$time1 = Measure-Command {
    $result1 = $processes | Where-Object { $_.CPU -gt 50 }
}
$count1 = $result1.Count

# 方法2:使用 .Where() 方法(本地数组方法)
$time2 = Measure-Command {
    $result2 = $processes.Where({ $_.CPU -gt 50 })
}
$count2 = $result2.Count

# 输出对比
[PSCustomObject]@{
    Method          = "Where-Object (Pipeline)"
    TimeMs          = [math]::Round($time1.TotalMilliseconds, 2)
    ResultCount     = $count1
} | Format-List

[PSCustomObject]@{
    Method          = ".Where() (Method)"
    TimeMs          = [math]::Round($time2.TotalMilliseconds, 2)
    ResultCount     = $count2
} | Format-List

🔍 笔者笔记本输出:
PS XXXXXXXXXXXXX> .\test.ps1


Method      : Where-Object (Pipeline)
TimeMs      : 110.4
ResultCount : 4910





Method      : .Where() (Method)
TimeMs      : 42.45
ResultCount : 4910
💡 关键解析:
  • .Where() 是 .NET 方法,直接操作数组,无管道创建/销毁开销
  • Where-Object 是 cmdlet,每次传递对象都经过 PowerShell 管道引擎
  • 适用场景
    • 小数据量(<100):差异可忽略
    • 大数据量(>1000)或循环内:优先用 .Where()

📌 扩展:同理,.ForEach({})ForEach-Object 更快。


✅ 第6天能力验证总结

作业考察能力实战价值
1Select-String + 正则提取快速定位系统/应用日志中的关键事件
2正则多匹配 + 去重标准化数据清洗、安全审计(如提取凭证)
3性能敏感代码优化编写高效自动化脚本,避免“慢脚本”

🚀 进阶建议

  • 对于超大日志(GB 级),考虑结合 Get-Content -ReadCount 1000 分块处理
  • 使用 [regex]::Escape() 转义用户输入,防止正则注入
  • 在函数中返回 [PSCustomObject] 而非纯字符串,便于后续结构化处理
代码转载自:https://pan.quark.cn/s/8ce4326d996e 对于在 CentOS 7 系统中修改网卡配置文件后无法使设置生效的情况,经过实践验证,可以通过使用 nmcli 命令来进行调整。完成修改之后,需要重新启动虚拟机以使更改生效,这样操作流程即告完成。如果设置仍然无法生效,则表明虚拟机在启动过程中所获取的 IP 地址配置并非针对 eth0,此时可以对其它网卡的配置文件进行修改或将其移除。在 CentOS 7 系统中,网络配置的管理机制早期版本存在差异,主要体现为采用了 Network Manager 服务来负责网络接口的管理。在某些情形下,尽管修改了 `/etc/sysconfig/network-scripts` 目录下的 `ifcfg-eth0` 文件,但网络配置却未能即时生效。此类问题的发生通常源于 CentOS 7 采用了不同于以往的配置读取方法。接下来将具体阐述如何借助 nmcli 命令来处理这一挑战。 以 root 用户身份登录系统并打开终端界面。nmcli 是 Network Manager 提供的命令行界面工具,它支持在命令行环境下执行网络连接的建立、编辑、查询及管理任务。针对修改 eth0 网卡配置的需求,可以遵循以下步骤进行操作: 1. 导航至 `/etc/sysconfig/network-scripts` 目录: ``` cd /etc/sysconfig/network-scripts ``` 2. 检查该目录内是否存在 `ifcfg-eth0.bak` 文件,该备份文件可能是先前调整配置时遗留下来的,若存在可能造成冲突。若发现该文件,可以选择将其删除: ``` [root@localhost netw...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值