环境
操作系统Win10 1909,PowerShell版本($PSVersionTable.PSVersion.ToString()
)6.2.3。$PSCulture
和$PSUICulture
这回都是ja-JP
,放心好了。暂且用自带的终端。
缘由
之前在现场工作时,由于实在没有称手的工具,Visual Studio又没办法续许可,想用grep的话,只好用sakura之类的文本编辑器,非常难受。于是我摸了四个月的鱼,用PowerShell 5.1做了一个ww
但是后来退场了,脚本拿不走,只好重写一个。这次只花了一天时间www
代码
D:\work\util\simpleFind.ps1
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline)]
[Object]
$Path = '.',
[Parameter()]
[string]
$PathFilter = '.*\.(cs|cshtml|css|js|json)$',
[Parameter()]
[Object]
$Encoding = 'UTF8',
[Parameter(Mandatory)]
[string]
$Pattern,
[Parameter()]
[switch]
$FindLines
)
begin {
# file counter
$Script:fileCounter = [UInt32]0;
if ($FindLines) {
# found counter
$Script:lineCounter = [UInt32]0;
}
function findLine {
param (
[Microsoft.PowerShell.Commands.GroupInfo]$resultGroup
)
foreach ($result in $resultGroup.Group) {
# line
$Script:lineCounter += [UInt32]1;
Write-Host (" {0,5} " -f $result.LineNumber) `
-ForegroundColor White `
-BackgroundColor DarkBlue `
-NoNewline;
Write-Host $result.Line.Trim();
}
}
}
process {
Set-Variable -Name 'files' -Value {
if ($Path -is [string] -and (Test-Path $Path)) {
# when it's a path string
return Get-ChildItem -Path $Path -Recurse;
} elseif ($Path -is [System.IO.FileInfo]) {
# when it's a file
return $Path;
} else {
# when it's a directory or etc.
return $null;
}
}.InvokeReturnAsIs();
# avoid wasteful process
if ($null -eq $files) {
return;
}
# main part
Set-Variable -Name 'resultSet' -Value ($files |
Where-Object Name -Match $PathFilter |
Select-String -Encoding $Encoding -AllMatches $Pattern |
Select-Object -Property Path, LineNumber, Line |
Sort-Object -Property Path, LineNumber);
# when found
if ($null -ne $resultSet) {
Set-Variable -Name 'resultGroupSet' -Value ($resultSet |
Group-Object -Property Path);
foreach ($resultGroup in $resultGroupSet) {
# file path
$Script:fileCounter += [UInt32]1;
Write-Host $resultGroup.Name `
-ForegroundColor White `
-BackgroundColor DarkBlue;
if ($FindLines) {
findLine($resultGroup);
}
}
}
}
end {
Write-Host ("{0} file(s) found" -f $Script:fileCounter);
if ($FindLines) {
Write-Host ("{0} line(s) found" -f $Script:lineCounter);
}
}
用例
前提:在预先加载的$PROFILE
里写了这些:
New-PSDrive `
-Name 'W' `
-PSProvider FileSystem `
-Root 'D:\work';
临时装载了一个驱动器。
要查的项目是这个:W:\prj\HelloMVC\
# find which files have "information"
W:\util\simpleFind.ps1 -Path 'W:\prj\HelloMVC\' -Pattern 'information'
# same as ahead. using pipeline
'W:\prj\HelloMVC\' | W:\util\simpleFind.ps1 -Pattern 'information'
# also using pipeline. just like what we usually do
Get-ChildItem 'W:\prj\HelloMVC\' -Recurse | W:\util\simpleFind.ps1 -Pattern 'information'
# find files and lines
W:\util\simpleFind.ps1 -Path 'W:\prj\HelloMVC\' -Pattern 'information' -FindLines
后记
没什么好说的。告别上一个现场,为之后的工作和生活做准备就是了。