“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第n篇文章,点击查看活动详情”
背景
一个普通的早晨, 我突然回忆起几个月前写的代码段,但忘记写在哪个文件里面了,这时我拿起 everything, fd 一看, 哦嚯,只能搜文件,简单打开几个文件看了下,并没有找到我想要的内容。这时,我就一拍脑袋,热了。。整个命令搜索搞定它,于是有了此搜索工具
具体代码
function search ($searchKey) {
$target = "E:\git\md-set"
cd $target
$script:count = 0
function searchDirectory ($searchKey) {
$files = get-childItem *.md && Get-ChildItem -Directory
for ($i = 0; $i -lt $files.Count; $i++) {
if(Test-Path $files[$i] -PathType Container) {
Set-Location $files[$i]
return searchDirectory($searchKey)
} else {
$current = $files[$i]
$targetContext = Get-Content $current | Select-String -Pattern $searchKey -CaseSensitive -SimpleMatch
if($targetContext.Length) {
Write-Host $targetContext
Write-Host "内容位于: $current"
$script:count++
}
}
}
}
Measure-Command -Expression {
searchDirectory($searchKey)
} | Select-Object -Property TotalMilliseconds
cd $target
Write-Host "有 $count 个结果"
}
调用效果如下
github地址
踩坑之旅
函数调用也许不需要()
powershell 跟 javascript 函数调用不同的是,如果你的函数没有参数,就不需要用()..这个特性挺奇葩的
获取所有目标文件并深度递归
Get-ChildItem
[[-Path] <string[]>]
[[-Filter] <string>]
[-Include <string[]>]
[-Exclude <string[]>]
[-Recurse]
[-Depth <uint32>]
[-Force]
[-Name]
[-Attributes <FlagsExpression[FileAttributes]>]
[-FollowSymlink]
[-Directory]
[-File]
[-Hidden]
[-ReadOnly]
[-System]
[<CommonParameters>]
目标语法:Get-ChildItem -Recurse, 但是真这样做也不行,感觉有点那啥,于是用程序设计去解决它: 判断目录,再递归处理
get-childItem *.md && Get-ChildItem -Directory
作用域
变量作用域是 powershell的一大坑点,但从大局来考虑确实需要,但不管怎样,对开发者确实不又好,少不了又要去翻文档:
PowerShell 范围
PowerShell 支持以下范围:
- 全局:PowerShell 启动时或创建新会话或运行空间时生效的范围。 在全局范围内创建 PowerShell 时存在的变量和函数,例如自动变量和首选项变量。 PowerShell 配置文件中的变量、别名和函数也在全局范围内创建。 全局范围是会话中的根父范围。
- 本地:当前范围。 本地范围可以是全局范围或任何其他范围。
- 脚本:脚本文件运行时创建的作用域。 只有脚本中的命令在脚本范围内运行。 对于脚本中的命令,脚本范围是本地范围。
范围修饰符
变量、别名或函数名称可以包含以下任一可选作用域修饰符:
-
global:- 指定名称存在于 全局 范围内。 -
local:- 指定 名称存在于本地 范围内。 当前范围始终是 本地 范围。 -
private:- 指定名称为 Private ,并且仅对当前作用域可见。备注
private不是作用域。 这是 一个选项 ,用于更改定义项的范围之外的项的可见性。 -
script:- 指定 脚本 范围中存在名称。 脚本 范围是最近的上级脚本文件的范围,如果没有最近的上级脚本文件,则为 Global 。 -
using:- 用于通过 cmdlet(如Start-Job和Invoke-Command)运行脚本时访问另一个作用域中定义的变量。 -
workflow:- 指定工作流中存在名称。 注意:PowerShell v6 及更高版本不支持工作流。 -
`` - PowerShell PSDrive 提供程序创建的修饰符。 例如:
命名空间 说明 Alias:在当前作用域中定义的别名 Env:在当前范围内定义的环境变量 Function:在当前作用域中定义的函数 Variable:在当前作用域中定义的变量
脚本的默认范围是脚本范围。 函数和别名的默认范围是本地范围,即使它们在脚本中定义也是如此。
所以要想使用 script 去修饰
时间统计
Measure-Command -Expression { } 这个挺好,配合 对象选择,体验最好的一次。。
完结体验
这次折腾起码解决了搜索问题,但还有优化空间,后续有空会考虑继续优化。
从代码体验上来说,powershell 语法大部分是符合直觉的,但函数调用,作用域这两块还是令人不满意,希望继续加油,不要让zx 超越了