## 24.4 通过Select-String使用正则表达式
现在我们终于到了本章的精华之处。我们使用一些IIS日志文件作为示例,这是由于IIS日志是纯文本,而这正是正则表达式的用武之地。如果能将这些日志以更面向对象的风格读取到PowerShell中,那再好不过。可惜不能……所以只能使用正则表达式。
让我们先在日志文件中查找40x错误。这类错误主要是“找不到文件”以及其他错误,我们希望为Web开发人员生成一个缺失文件的报表。日志文件中,每一个HTTP请求为一行,每行又被分为以空格分割的域。我们还有一些文件名称中包含“401”等,比如“error401.html”,我们不希望这部分结果出现在我们的结果中。我们将会指定一个类似`\s40[0-9]\s`的正则表达式,因为通过在40x错误之前和之后匹配空格,该表达式将能够匹配从400到499的错误。下面是我们使用的命令。
```
<pre class="dai_ma_wu_xing_hao">```
PS C:\logfiles> get-childitem -filter *.log -recurse | select-string -pattern
"\s40[0-9]\s" | format-table Filename,LineNumber,Line –wrap
```
```
注意,我们将当前目录变更为C:\\logfiles,开始运行命令。我们通过寻找所有以.log结尾的文件,并递归查找子目录。这可以确保所有的日志文件都可以被包含在输出结果之内。接下来我们使用`Select-String`,提供正则表达式作为参数。该命令的结果是一个类型为MatchInfo的对象;这里使用`Format-Table`命令,使得显示结果包含文件名称、行号以及包含匹配结果的文本。这使得找到缺失文件非常容易。然后我们将报表给予Web开发人员。
接下来,我们希望扫描所有被基于Gecko浏览器访问过的文件。开发人员告诉我们,使用该类浏览器访问我们的网站的用户会遇到一些问题,他们希望找到具体被访问的文件。他们还希望将问题范围缩减为使用Windows NT6.2操作系统运行浏览器的用户,这意味着我们需要在`user-agnet`中寻找类似下面的字符串。
```
<pre class="dai_ma_wu_xing_hao">```
(Windows+NT+6.2;+WOW64;+rv:11.0)+Gecko
```
```
开发人员强调是否为64位操作系统无关紧要,因此我们不希望`U``ser-agent`中仅是包含“WOW64”的结果。最终我们得到这个正则表达式:`6\.2;[\w\W]+\+Gecko`——
让我们对其进行分解。
- `6\.2;`——这就是“6.2”;我们使用转义字符将句号变为字面意思上的句号,而不是作为单字符的通配符。
- `[\w\W]+` ——一个或多个字符或非字符——换句话说是任何内容。
- `\+Gecko` ——也就是字面意义上的加号,然后是“Gecko”。
下面是从日志文件返回匹配行的命令,还包含前几行的返回结果。
```
<pre class="dai_ma_wu_xing_hao">```
PS C:\logfiles> get-childitem -filter *.log -recurse |
➥select-string -pattern "6\.2;[\w\W]+\+Gecko"
W3SVC1\u_ex120420.log:14:2012-04-20 21:45:04 10.211.55.30 GET
/MyApp1/Testpage.asp - 80 - 10.211.55.29
Mozilla/5.0+(Windows+NT+6.2;+WOW64;+rv:11.0)+Gecko/20100101+Firefox/11.0
200 0 0 1125
W3SVC1\u_ex120420.log:15:2012-04-20 21:45:04 10.211.55.30 GET /TestPage.asp-
80 - 10.211.55.29
Mozilla/5.0+(Windows+NT+6.2;+WOW64;+rv:11.0)+Gecko/20100101+Firefox/11.0
200 0 0 1 109
```
```
这次我们保持输出结果为默认格式,而不是将结果发送给用于格式化的Cmdlet。
在最后一个例子中,将IIS日志文件变为Windows安全日志。事件日志实体中包含`Message`属性,该属性中包含关于事件信息的细节。遗憾的是,该信息并没有良好的格式化以便于人们阅读,也不易于计算机解析。我们希望查找所有事件ID为4624的事件,该事件代表账户登录事件(该ID代表的含义可能根据Windows版本的不同而有所不同;我们的示例是在Windows Server 2008 R2上)。但我们只希望查看账户名称以“WIN”开头的登录信息,这些账户都与在域中的计算机账户关联。另外,我们还要求账户结尾必须是从`TM20$`到`TM40$`的字符,这些是我们感兴趣的特定计算机。我们需要的正则表达式大概如下:`WIN[\W\w]+TM[234][0-9]\$` ——注意我们需要使用转义符号将末尾的`$`进行转义,因此该符号不会被解释成字符串结尾标记。我们需要包含`[\W\w]`(非字符和字符),这是由于我们的账户名称中可能包含连字符,该连字符无法与`\w`字符类匹配。因此最终下面是我们的命令。
```
<pre class="dai_ma_wu_xing_hao">```
PS C:\> get-eventlog -LogName security | where { $_.eventid -eq 4624 } |
➥select -ExpandProperty message | select-string -pattern
➥"WIN[\W\w]+TM[234][0-9]\$"
```
```
在开始部分,我们使用`Where-Object`,从而仅使得ID为4624的事件被筛选出来。然后我们将`Message`属性的内容存入纯字符串,并通过管道将其传输给`Select-String`。注意,这将会输出匹配的信息文本;如果我们的目标是输出所有匹配的事件,我们需要使用另一种方式。
```
<pre class="dai_ma_wu_xing_hao">```
PS C:\> get-eventlog -LogName security | where { $_.eventid -eq 4624 -and
➥$_.message -match "WIN[\W\w]+TM[234][0-9]\$" }
```
```
这里,我们不是输出`Message`属性的内容,而是查找`Message`属性匹配正则表达式的记录——接下来输出整个Event对象。接下来所使用的命令取决于结果希望输出的形式。
- 版权信息
- 版权声明
- 内容提要
- 序言
- 前言
- 作者简介
- 译者简介
- 致谢
- 第1章 背景介绍
- 1.1 为什么要重视PowerShell
- 1.1.1 没有PowerShell
- 1.1.2 拥有PowerShell
- 1.2 现在只剩下“PowerShell”,而不是“Windows PowerShell”
- 1.3 本书适用读者
- 1.4 如何使用本书
- 1.4.1 主要章节
- 1.4.2 动手实验
- 1.4.3 代码示例
- 1.4.4 进一步学习
- 1.4.5 补充说明
- 1.5 搭建自己的实验环境
- 1.6 安装Windows PowerShell
- 1.7 联系我们
- 1.8 赶紧使用PowerShell吧
- 第2章 初识PowerShell
- 2.1 选择你的“武器”
- 2.1.1 控制台窗口
- 2.1.2 集成脚本环境(ISE)
- 2.2 重新认识代码输入
- 2.3 常见误区
- 2.4 如何查看当前版本
- 2.5 动手实验
- 第3章 使用帮助系统
- 3.1 帮助系统:发现命令的方法
- 3.2 可更新的帮助
- 3.3 查看帮助
- 3.4 使用帮助系统查找命令
- 3.5 帮助详解
- 3.5.1 参数集和通用参数
- 3.5.2 可选和必选参数
- 3.5.3 位置参数
- 3.5.4 参数值
- 3.5.5 发现命令示例
- 3.6 访问“关于”主题
- 3.7 访问在线帮助
- 3.8 动手实验
- 3.9 动手实验答案
- 第4章 运行命令
- 4.1 无需脚本,仅仅是运行命令
- 4.2 剖析一个命令
- 4.3 Cmdlet命名惯例
- 4.4 别名:命令的昵称
- 4.5 使用快捷方式
- 4.5.1 简化参数名称
- 4.5.2 参数名称别名
- 4.5.3 位置参数
- 4.6 小小作弊一下:Show-Command
- 4.7 对扩展命令的支持
- 4.8 处理错误
- 4.9 常见误区
- 4.9.1 输入Cmdlet名称
- 4.9.2 输入参数
- 4.10 动手实验
- 第5章 使用提供程序
- 5.1 什么是提供程序
- 5.2 FileSystem的结构
- 5.3 理解文件系统与其他数据存储的类似之处
- 5.4 使用文件系统
- 5.5 使用通配符与字面路径
- 5.6 使用其他提供程序
- 5.7 动手实验
- 5.8 进一步学习
- 5.9 动手实验答案
- 第6章 管道:连接命令
- 6.1 一个命令与另外一个命令连接:为你减负
- 6.2 输出结果到CSV或XML文件
- 6.2.1 输出结果到CSV
- 6.2.2 输出结果到XML
- 6.2.3 对比文件
- 6.3 管道传输到文件或打印机
- 6.4 转换成HTML
- 6.5 使用Cmdlets修改系统:终止进程和停止服务
- 6.6 常见误区
- 6.7 动手实验
- 6.8 动手实验答案
- 第7章 扩展命令
- 7.1 如何让一个Shell完成所有事情
- 7.2 关于产品的“管理Shell”
- 7.3 扩展:找到并添加插件
- 7.4 扩展:找到并添加模块
- 7.5 命令冲突和移除扩展
- 7.6 在非Windows操作系统
- 7.7 玩转一个新的模块
- 7.8 配置脚本:在启动Shell时预加载扩展
- 7.9 从Internet获取模块
- 7.10 常见误区
- 7.11 动手实验
- 7.12 动手实验答案
- 第8章 对象:数据的另一个名称
- 8.1 什么是对象
- 8.2 理解为什么PowerShell使用对象
- 8.3 探索对象:Get-Member
- 8.4 使用对象标签,也就是所谓的“属性”
- 8.5 对象行为,也就是所谓的“方法”
- 8.6 排序对象
- 8.7 选择所需的属性
- 8.8 在命令结束之前总是对象的形式
- 8.9 常见误区
- 8.10 动手实验
- 8.11 动手实验答案
- 第9章 深入理解管道
- 9.1 管道:更少的输入,更强大的功能
- 9.2 PowerShell如何传输数据给管道
- 9.3 方案A:使用ByValue进行管道输入
- 9.4 方案B:使用ByPropertyName进行管道传输
- 9.5 数据不对齐时:自定义属性
- 9.6 括号命令
- 9.7 提取属性的值
- 9.8 动手实验
- 9.9 进一步学习
- 9.10 动手实验答案
- 第10章 格式化及如何正确使用
- 10.1 格式化:让输出更加美观
- 10.2 默认格式
- 10.3 格式化表格
- 10.4 格式化列表
- 10.5 格式化宽列表
- 10.6 创建自定义列与列表条目
- 10.7 输出到文件、打印机或者主机上
- 10.8 输出到GridView中
- 10.9 常见误区
- 10.9.1 总是在最右边格式化
- 10.9.2 一次一个对象
- 10.10 动手实验
- 10.11 进一步学习
- 10.12 动手实验答案
- 第11章 过滤和比较
- 11.1 只获取必要的内容
- 11.2 左过滤
- 11.3 使用比较操作符
- 11.4 过滤对象的管道
- 11.5 使用迭代命令行模式
- 11.6 常见误区
- 11.6.1 请左过滤
- 11.6.2 何时允许使用$_
- 11.7 动手实验
- 11.8 进一步学习
- 11.9 动手实验答案
- 第12章 学以致用
- 12.1 定义任务
- 12.2 发现命令
- 12.3 学习如何使用命令
- 12.4 自学的一些技巧
- 12.5 动手实验
- 12.6 动手实验答案
- 第13章 远程处理:一对一及一对多
- 13.1 PowerShell远程处理的原理
- 13.2 WinRM概述
- 13.3 一对一场景的Enter-PSSession和Exit-PSSession
- 13.4 一对多场景的Invoke-Command
- 13.5 远程命令和本地命令之间的差异
- 13.5.1 Invoke-Command和–ComputerName对比
- 13.5.2 本地处理和远程处理对比
- 13.5.3 反序列化对象
- 13.6 深入探讨
- 13.7 远程处理的配置选项
- 13.8 常见误区
- 13.9 动手实验
- 13.10 进一步学习
- 13.11 动手实验答案
- 第14章 Windows管理规范
- 14.1 WMI概要
- 14.2 关于WMI的坏消息
- 14.3 探索WMI
- 14.4 选择你的武器:WMI或CIM
- 14.5 使用Get-WmiObject
- 14.6 使用Get-CimInstance
- 14.7 WMI文档
- 14.8 常见误区
- 14.9 动手实验
- 14.10 进一步学习
- 14.11 动手实验答案
- 第15章 多任务后台作业
- 15.1 利用PowerShell实现多任务同时处理
- 15.2 同步VS异步
- 15.3 创建本地作业
- 15.4 WMI作业
- 15.5 远程处理作业
- 15.6 获取作业执行结果
- 15.7 使用子作业
- 15.8 管理作业的命令
- 15.9 调度作业
- 15.10 常见困惑点
- 15.11 动手实验
- 15.12 动手实验答案
- 第16章 同时处理多个对象
- 16.1 对于大量管理的自动化
- 16.2 首选方法:“批处理”Cmdlet
- 16.3 CIM/WMI方式:调用方法
- 16.4 后备计划:枚举对象
- 16.5 常见误区
- 16.5.1 哪一种是正确的方式
- 16.5.2 WMI方法与Cmdlet对比
- 16.5.3 方法文档
- 16.5.4 ForEach-Object相关误区
- 16.6 动手实验
- 16.7 动手实验答案
- 第17章 安全警报
- 17.1 保证Shell安全
- 17.2 Windows PowerShell的安全目标
- 17.3 执行策略和代码签名
- 17.3.1 执行策略设置
- 17.3.2 数字代码签名
- 17.4 其他安全措施
- 17.5 其他安全漏洞
- 17.6 安全建议
- 17.7 动手实验
- 第18章 变量:一个存放资料的地方
- 18.1 变量简介
- 18.2 存储值到变量中
- 18.3 使用变量:关于引号有趣的技巧
- 18.4 在一个变量中存储多个对象
- 18.4.1 与多值单一变量的单一对象交互
- 18.4.2 与多值单一变量的多个对象交互
- 18.4.3 与多个对象交互的其他方式
- 18.4.4 在PowerShell v3中展现属性和方法
- 18.5 双引号的其他技巧
- 18.6 声明变量类型
- 18.7 与变量相关的命令
- 18.8 针对变量的最佳实践
- 18.9 常见误区
- 18.10 动手实验
- 18.11 进一步学习
- 18.12 动手实验答案
- 第19章 输入和输出
- 19.1 提示并显示信息
- 19.2 Read-Host命令
- 19.3 Write-Host命令
- 19.4 Write-Output命令
- 19.5 其他输出方式
- 19.6 动手实验
- 19.7 进一步学习
- 19.8 动手实验答案
- 第20章 轻松实现远程控制
- 20.1 使得PowerShell远程控制更加容易
- 20.2 创建并使用可重用会话
- 20.3 利用Enter-PSSession命令使用会话
- 20.4 利用Invoke-Command命令使用会话
- 20.5 隐式远程控制:导入一个会话
- 20.6 使用断开会话
- 20.7 动手实验
- 20.8 进一步学习
- 20.9 动手实验答案
- 第21章 你把这叫作脚本
- 21.1 非编程,而更像是批处理文件
- 21.2 使得命令可重复执行
- 21.3 参数化命令
- 21.4 创建一个带参数的脚本
- 21.5 为脚本添加文档
- 21.6 一个脚本,一个管道
- 21.7 作用域初探
- 21.8 动手实验
- 21.9 动手实验答案
- 第22章 优化可传参脚本
- 22.1 起点
- 22.2 让PowerShell去做最难的工作
- 22.3 将参数定义为强制化参数
- 22.4 添加参数别名
- 22.5 验证输入的参数
- 22.6 通过添加详细输出获得易用性体验
- 22.7 动手实验
- 22.8 动手实验答案
- 第23章 高级远程控制配置
- 23.1 使用其他端点
- 23.2 创建自定义端点
- 23.2.1 创建会话配置
- 23.2.2 会话注册
- 23.3 启用多跳远程控制(multi-hop remoting)
- 23.4 深入远程控制身份验证
- 23.4.1 双向身份验证默认设置
- 23.4.2 通过SSL实现双向身份验证
- 23.4.3 通过受信任的主机实现双向身份验证
- 23.5 动手实验
- 23.6 动手实验答案
- 第24章 使用正则表达式解析文本文件
- 24.1 正则表达式的目标
- 24.2 正则表达式入门
- 24.3 通过-Match使用正则表达式
- 24.4 通过Select-String使用正则表达式
- 24.5 动手实验
- 24.6 进一步学习
- 24.7 动手实验答案
- 第25章 额外的提示,技巧以及技术
- 25.1 Profile、提示以及颜色:自定义Shell界面
- 25.1.1 PowerShell Profile脚本
- 25.1.2 自定义提示
- 25.1.3 调整颜色
- 25.2 运算符:-AS、-IS、-Replace、-Join、-Split、-IN、-Contains
- 25.2.1 –AS和–IS
- 25.2.2 –Replace
- 25.2.3 –Join和-Split
- 25.2.4 –Contains和-In
- 25.3 字符串处理
- 25.4 日期处理
- 25.5 处理WMI日期
- 25.6 设置参数默认值
- 25.7 学习脚本块
- 25.8 更多的提示、技巧及技术
- 第26章 使用他人的脚本
- 26.1 脚本
- 26.2 逐行检查
- 26.3 动手实验
- 26.4 动手实验答案
- 第27章 学无止境
- 27.1 进一步学习的思想
- 27.2 既然已经阅读了本书,那么我要从哪里开始呢
- 27.3 你会喜欢的其他资源
- 第28章 PowerShell备忘清单
- 28.1 标点符号
- 28.2 帮助文档
- 28.3 运算符
- 28.4 自定义属性与自定义列的语法
- 28.5 管道参数输入
- 28.6 何时使用$_
- 复习实验3
- 欢迎来到异步社区!