使用 help Select-String -ShowWindow
命令我们可以很容易的得到一份中文的帮助文档,其中有这样两段话:
- Select-String cmdlet 在输入字符串和文件中搜索文本和文本模式。你可以像使用 UNIX 中的 Grep 和 Windows 中的 Findstr 一样来使用它。可以键入“Select-String”或其别名“sls”。
- Select-String 类似于 UNIX 中的 Grep 命令和 Windows 中的 FindStr 命令。
熟悉 Linux/Unix 的朋友们都知道,grep 命令有这样如下常见的参数:
本文将使用 Select-String
来对这些功能进行一一实现。
由于 grep -n
是列出每一个符合条件的行号,而 PowerShell 默认就会输出行数,这里不再提此。
grep -r
)使用 Get-ChildItem -Path 文件路径 -Recurse | select-string -pattern "模式"
例子:我在 E:\sourcecode\bin\test
有一个文件 FactoryPattern.txt
和若干目录:
E:\sourcecode\bin\test>tree /f
卷 文档 的文件夹 PATH 列表
卷序列号为 0008-09A4
E:.
│ FactoryPattern.txt
├─1
│ │ FactoryPattern1.txt
│ └─1.1
│ FactoryPattern1.1.txt
├─2
│ FactoryPattern2.txt
└─3
FactoryPattern3.txt
用上述命令结果如下(因为我已经 cd 到此目录下了,故没指定 -Path)
PS E:\sourcecode\bin\test> Get-ChildItem -Recurse | Select-String -Pattern "干"
FactoryPattern.txt:9:mozzarella n. 意大利白色干酪
FactoryPattern.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on Italian
dishes.)
FactoryPattern.txt:15:reggiano n. 干酪
1\FactoryPattern1.txt:9:mozzarella n. 意大利白色干酪
1\FactoryPattern1.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on Ital
ian dishes.)
1\FactoryPattern1.txt:15:reggiano n. 干酪
1\1.1\FactoryPattern1.1.txt:9:mozzarella n. 意大利白色干酪
1\1.1\FactoryPattern1.1.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially o
n Italian dishes.)
1\1.1\FactoryPattern1.1.txt:15:reggiano n. 干酪
2\FactoryPattern2.txt:9:mozzarella n. 意大利白色干酪
2\FactoryPattern2.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on Ital
ian dishes.)
2\FactoryPattern2.txt:15:reggiano n. 干酪
3\FactoryPattern3.txt:9:mozzarella n. 意大利白色干酪
3\FactoryPattern3.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on Ital
ian dishes.)
3\FactoryPattern3.txt:15:reggiano n. 干酪
输出有点乱,看不出文件层次,不知道有没有更美观的方法, 希望有人能够给出建议。下图是 grep 的,也有点乱:
PS E:\sourcecode\bin\test> grep -nr "干"
1/1.1/FactoryPattern1.1.txt:9:mozzarella n. 意大利白色干酪
1/1.1/FactoryPattern1.1.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on
Italian dishes.)
1/1.1/FactoryPattern1.1.txt:15:reggiano n. 干酪
1/FactoryPattern1.txt:9:mozzarella n. 意大利白色干酪
1/FactoryPattern1.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on Itali
an dishes.)
1/FactoryPattern1.txt:15:reggiano n. 干酪
2/FactoryPattern2.txt:9:mozzarella n. 意大利白色干酪
2/FactoryPattern2.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on Itali
an dishes.)
2/FactoryPattern2.txt:15:reggiano n. 干酪
3/FactoryPattern3.txt:9:mozzarella n. 意大利白色干酪
3/FactoryPattern3.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on Itali
an dishes.)
3/FactoryPattern3.txt:15:reggiano n. 干酪
FactoryPattern.txt:9:mozzarella n. 意大利白色干酪
FactoryPattern.txt:11:parmesan n. 帕尔马干酪 adj. 巴马的(a hard, dry cheese used in grated form, especially on Italian
dishes.)
FactoryPattern.txt:15:reggiano n. 干酪
在 https://antjanus.com/blog/web-development-tutorials/how-to-grep-in-powershell/ 找到了美观输出的方法。显示的有点不对…
Get-ChildItem -Recurse | Select-String -Pattern "干" | Select Filename, LineNumber, Line, Path | Format-Table
PS E:\sourcecode\bin\test> Get-ChildItem -Recurse | Select-String -Pattern "干" | Select Filename, LineNumber, Line, Pat
h | Format-Table
Filename LineNumber Line Path
-------- ---------- ---- ----
FactoryPattern.txt 9 mozzarella n. 意大利白色干酪 E:\sourcecode\bin\test\Fac...
FactoryPattern.txt 11 parmesan n. 帕尔马干酪 adj... E:\sourcecode\bin\test\Fac...
FactoryPattern.txt 15 reggiano n. 干酪 E:\sourcecode\bin\test\Fac...
FactoryPattern1.txt 9 mozzarella n. 意大利白色干酪 E:\sourcecode\bin\test\1\F...
FactoryPattern1.txt 11 parmesan n. 帕尔马干酪 adj... E:\sourcecode\bin\test\1\F...
FactoryPattern1.txt 15 reggiano n. 干酪 E:\sourcecode\bin\test\1\F...
FactoryPattern1.1.txt 9 mozzarella n. 意大利白色干酪 E:\sourcecode\bin\test\1\1...
FactoryPattern1.1.txt 11 parmesan n. 帕尔马干酪 adj... E:\sourcecode\bin\test\1\1...
FactoryPattern1.1.txt 15 reggiano n. 干酪 E:\sourcecode\bin\test\1\1...
FactoryPattern2.txt 9 mozzarella n. 意大利白色干酪 E:\sourcecode\bin\test\2\F...
FactoryPattern2.txt 11 parmesan n. 帕尔马干酪 adj... E:\sourcecode\bin\test\2\F...
FactoryPattern2.txt 15 reggiano n. 干酪 E:\sourcecode\bin\test\2\F...
FactoryPattern3.txt 9 mozzarella n. 意大利白色干酪 E:\sourcecode\bin\test\3\F...
FactoryPattern3.txt 11 parmesan n. 帕尔马干酪 adj... E:\sourcecode\bin\test\3\F...
FactoryPattern3.txt 15 reggiano n. 干酪 E:\sourcecode\bin\test\3\F...
我们注意到 Path 这一栏下面的部分内容被省略号替换掉了。怎么让它显示全呢?我们需要两个步骤
一个例子
$results | Format-Table -AutoSize | Out-File -Width 512 C:\log.txt -Append
参考 How do I use Format-Table without truncation of values?
grep -i
)使用开关参数(SwitchParameter) -CaseSensitive
。
默认情况下,匹配项不区分大小写。
grep -c
)PS C:\>$f = select-string -path audit.log -pattern "logon failed"
PS C:\>$f.count
第二个命令使用对象数组的 Count 属性来显示找到的匹配项数
比如说,有 4 行有 logon failed
这个 pattern,输出就是 4。
grep -C N
)使用 -Context
PS C:\>$f = select-string -path audit.log -pattern "logon failed" -context 2, 3
此命令将在 Audit.Log 文件中搜索短语“logon failed”。它使用 Context 参数来捕获匹配项的前 2 行和后 3 行。
使用开关参数 -AllMatches
在每个文本行中搜索多个匹配项。在没有此参数的情况下,Select-String
只会查找每个文本行中的第一个匹配项。
这个参数帮助文档是这样写的,但是其作用我也不太知道,因为 Select-String 默认好像也可以以搜全。
grep -e 表达式
)来自 https://cloud.tencent.com/developer/ask/41837
例如搜索 C:\Logs that contain the words "VendorEnquiry"和“Failed”的所有文件
Get-ChildItem C:\Logs |
where { $_ | Select-String -Pattern 'VendorEnquiry' } |
where { $_ | Select-String -Pattern 'Failed' } |
...
改进方法一,可以用一个筛选器来简化这个过程来匹配多个模式,而不是手动编写每个 Select-String 调用。
filter MultiSelect-String( [string[]]$Patterns ) {
# Check the current item against all patterns.
foreach( $Pattern in $Patterns ) {
# If one of the patterns does not match, skip the item.
$matched = @($_ | Select-String -Pattern $Pattern)
if( -not $matched ) {
return
}
}
# If all patterns matched, pass the item through.
$_
}
Get-ChildItem C:\Logs | MultiSelect-String 'VendorEnquiry','Failed',...
如果要按任意顺序匹配这两个单词,使用:
Get-ChildItem C:\Logs| select-string -pattern '(VendorEnquiry.*Failed)|(Failed.*VendorEnquiry)'
grep -v
)使用开关参数 -NotMatch
查找与指定的模式不匹配的文本。
grep -q
)使用开关参数 -Quiet
返回布尔值(true 或 false),而不是 MatchInfo 对象。如果找到该模式,则该值为“true”;否则为“false”。
grep -f
)grep -f
即 grep --file=filename
。其中 filename 指的是一个含有多行文本的文件名,而每行文本是一个匹配模式。
Get-Content .\doc.txt | Select-String -Pattern (Get-Content .\regex.txt)
其中 .\regex.txt 是那个每行都是一个匹配模式的文件,而 .\doc.txt 则是我们要搜索的文件。
参考 https://stackoverflow.com/questions/15199321/powershell-equivalent-to-grep-f
至于 grep
的 -w word
、 -l
和 -h
没见过实际例子,这里不提。
突然发现 PowerShell 下使用 grep 可以搜中文,而 cmd 下面的搜不了…
这就是说使用 PowerShell 既可以使用 Linux/Unix 命令带来的便捷还可以使用 PowerShell 提供的命令,就好像手上有了两把武器。
当然此文侧重在简单对比,Select-String 和 grep 的其他高级用法这里并没有涉及。