PowerShell สำหรับผู้คน: ทำให้เชลล์ทำงานเพื่อคุณ
นามแฝงเป็นเพียงทางเลือกชื่อคำสั่งสั้นๆ แทนที่จะพิมพ์ Get-Process คุณสามารถพิมพ์ ps ได้ แม้ว่าฉันจะไม่สามารถทำมันพังได้ การใช้นามแฝงที่พรอมต์คำสั่งเป็นวิธีที่ดีในการเร่งงานของคุณและลดการพิมพ์ผิด แม้ว่าฉันจะไม่พิมพ์สิ่งนี้ลงในสคริปต์:
gsv | ? status -eq runningเมื่อได้รับแจ้งก็รวดเร็วและได้ผลลัพธ์ที่ต้องการ อย่างไรก็ตาม คุณไม่สามารถสร้างนามแฝงสำหรับคำสั่งและพารามิเตอร์ของคำสั่งได้ ตัวอย่างเช่น ฉันชอบพารามิเตอร์ -First และ -Last ที่มี Select-Object แต่ฉันไม่สามารถสร้างนามแฝงที่เทียบเท่ากับ Select-Object -last 10 ได้ อย่างไรก็ตาม สิ่งที่คุณ ทำได้ ทำได้คือสร้าง wrapper ของคุณเองรอบๆ คำสั่งและใส่นามแฝงลงไป นี่คือฟังก์ชันที่ฉันเขียนสำหรับ Select-Object -Last X
#requires -version 3.0
Function Select-Last {
<#
.Synopsis
Select last X number of objects
.Description
This command takes pipelined input and selects the last specified number of objects which are then written to the pipeline.
There is a trade off of convenience for performance. For a very large number processed objects, use Select-Object directly
.Example
PS C:\> dir c:\scripts\*.ps1 | sort lastwritetime | last 5
.Notes
Last Updated: 8/25/2014
Version : 0.9
.Link
Select-Object
#>
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory,HelpMessage="How many objects do you want to get?")]
[ValidateScript({$_ -gt 0})]
[int]$Last,
[Parameter(Position=1,Mandatory,ValueFromPipeline)]
[object]$InputObject
)
Begin {
Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"
Write-Verbose -Message "Selecting last $Last objects"
#initialize an array to hold all incoming objects
$data=@()
#initialize a counter
$total=0
#track when the command started in order to calculate how long the command took to complete.
$start=Get-Date
} #begin
Process {
$total++
if ($total -le $Last) {
#add each piped object to temporary array
$data+=$InputObject
}
else {
#move all items in the array up one
$data = $data[1..$Last]
#add the new item
$data+=$InputObject
}
} #process
End {
#write the results
$data
$end = Get-Date
Write-Verbose -Message "Processed $total items in $($end-$start)"
Write-Verbose -Message "Ending $($MyInvocation.Mycommand)"
} #end
}
Set-Alias -Name Last -Value Select-Lastคุณจะสังเกตเห็นว่าส่วนสุดท้ายของข้อมูลโค้ดของฉันกำลังกำหนดนามแฝงที่เรียกว่า Last ซึ่งอ้างอิงถึงฟังก์ชันนี้ แต่ตอนนี้ฉันมีบางอย่างที่ใช้งานง่ายและรวดเร็วเมื่อได้รับพร้อมท์ PowerShell
dir c:\work\*.txt | sort lastwritetime | last 5คุณจะต้องหาวิธีที่ดีที่สุดในการรวม cmdlet ในกรณีนี้ ฉันกำลังนำแต่ละไพพ์ในออบเจ็กต์และเพิ่มลงในอาร์เรย์ โดยคงไว้เฉพาะจำนวนรายการที่ระบุเท่านั้น เมื่อเพิ่มแต่ละรายการแล้ว รายการอื่นๆ จะถูกย้าย "ขึ้น" ในอาร์เรย์
โปรดทราบว่าอาจมีข้อเสียระหว่างความสะดวกและประสิทธิภาพ คำสั่งนี้ใช้นามแฝงและฟังก์ชันที่กำหนดเองของฉัน:
Measure-command {1..5000 | last 3}ใช้เวลา 237ms ในขณะที่แนวทาง Select-Object:
Measure-command {1..5000 | select -Last 3}ใช้เวลาเพียง 49ms แต่ฉันพนันได้เลยว่าคุณอาจยินดีที่จะยอมรับการแลกเปลี่ยนนั้นเพื่อบันทึกการพิมพ์บางส่วน แน่นอนว่าหากมีคำสั่ง Last ก็ควรมีคำสั่ง First
Function Select-First {
<#
.Synopsis
Select first X number of objects
.Description
This command takes pipelined input and selects the first specified number of objects which are then written to the pipeline.
.Example
PS C:\> get-process | sort WS -descending | first 5
.Notes
Last Updated: 8/25/2014
Version : 0.9
.Link
Select-Object
#>
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory,HelpMessage="How many objects do you want to get?")]
[ValidateScript({$_ -gt 0})]
[int]$First,
[Parameter(Position=1,Mandatory,ValueFromPipeline)]
[object]$InputObject
)
Begin {
Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"
Write-Verbose -Message "Selecting first $First objects"
#track when the command started in order to calculate how long the command took to complete.
$start=Get-Date
#initialize a counter
$i=0
} #begin
Process {
#add each piped object to temporary array
$i++
if ($i -le $First) {
$InputObject
}
else {
#we're done here
Write-Verbose "Limit reached"
$end = Get-Date
Write-Verbose -Message "Processed $($data.count) items in $($end-$start)"
Write-Verbose -Message "Ending $($MyInvocation.Mycommand)"
#bail out
break
}
} #process
End {
#not used
} #end
}
Set-Alias -Name First -Value Select-Firstในด้านประสิทธิภาพ การทำเช่นนี้ง่ายกว่าเพราะสิ่งที่ฉันต้องทำคือนับการไปป์ในอ็อบเจ็กต์และประกันตัวออกเมื่อถึงขีดจำกัด
ps | sort ws -des | first 3ในตัวอย่างนี้ ฉันไม่เพียงใช้ประโยชน์จากนามแฝงเท่านั้น แต่ยังรวมถึงพารามิเตอร์ตำแหน่งด้วย และต้องพิมพ์ชื่อพารามิเตอร์ให้เพียงพอเท่านั้น เพื่อให้ PowerShell รู้ว่าฉันต้องการอะไร
มีวิธีต่างๆ มากมายที่ทำให้ PowerShell เป็นมิตรกับคีย์บอร์ดมากขึ้น แม้ว่าอาจต้องใช้เวลาแก้ไขเล็กน้อยในส่วนของคุณก็ตาม ครั้งต่อไปเราจะดูทางเลือกอื่น
