iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0

對應《30天挑戰精通 PowerShell》一書的第 12 章

今天來深入探討如何在 PowerShell 中進行篩選和比較,使其能更有效地處理資料。透過理解篩選技巧和比較運算子的使用,將能夠從大量的資訊中快速擷取出有用的內容,提升工作效率。


讓 Shell 只給你需要的內容

在處理大量資料時,取得過多的資訊可能會讓人不知所措。PowerShell 提供了兩種通用的模型來精簡結果,兩種方法都稱為篩選( filtering )。

第一種方法

透過 cmdlet 本身提供的 Parameter 去篩選出你指定的內容,舉例,當我們執行 Get-ChildItem 時,可以透過 -Name 去 filter 出包含檔案名稱包含 txt 字眼,換句話說,嘗試指示「擷取資訊的 cmdlet 」只擷取「你指定的內容」。

範例

# Gets the items and child items in one or more specified locations.
PS /Users/kanglin/code/30days> Get-ChildItem

    Directory: /Users/kanglin/code/30days

UnixMode         User Group         LastWriteTime         Size Name
--------         ---- -----         -------------         ---- ----
-rw-r--r--    kanglin staff       2024/9/24 22:14           63 aliases.txt
-rw-r--r--    kanglin staff       2024/9/24 13:09           90 modules.txt
-rw-r--r--    kanglin staff       2024/9/26 10:43        29233 result.json
-rw-r--r--    kanglin staff       2024/9/26 10:47         2943 Untitled.ipynb

PS /Users/kanglin/code/30days> Get-ChildItem -Name *.txt
aliases.txt
modules.txt

第二種方法

透過 pipeline,迭代式的先接收第一組 cmdlet 提供的內容後,再使用第二組 cmdlet( Where-Object )在管線中篩選物件。

範例

# 列出系統中使用 CPU 時間超過一定值的 Process。
PS /Users/kanglin/code/30days> Get-Process | Where-Object { $_.CPU -gt 100 }

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      0     0.00      75.03     517.71   24419   1 Anytype
      0     0.00      30.06     349.13   24420   1 Anytype Helper
      0     0.00     131.83   1,582.31   24423   1 Anytype Helper
      0     0.00      92.77     749.49   24422   1 anytypeHelper
      0     0.00      15.08     272.49   24106   1 AXVisualSupport
      0     0.00     125.48     764.37   24428   1 ChatGPT
      0     0.00      14.84     377.43   25076   1 Code Helper (GP
      0     0.00      26.41     138.41   24088   1 ControlCenter
      0     0.00      21.20     324.91   24096   1 corespeechd
      0     0.00      22.70     105.63   24394   1 CursorUIViewSer
      0     0.00      29.98     162.85   41705   1 Easydict
      0     0.00      38.78     181.01   25070   1 Electron
      0     0.00      10.38     107.72   24138   1 fileproviderd
      0     0.00      42.23     176.45   24102   1 Finder
      0     0.00     155.28   1,614.23   24576   1 Google Chrome

解釋

  • Where-Object 用於篩選物件。
  • $_. 代表管線中當前的物件。
  • -eq 是比較運算子,表示「等於」。

篩選左移

將篩選條件儘早應用,能夠提升命令的執行效率。這被稱為「篩選左移」,意思是在管線的左側盡可能地進行篩選。

篩選左移這個技術的缺點在於,每個 cmdlet 都可以實作自己的特定篩選方式,而且每個 cmdlet 在執行篩選的能力亦有所差異。

然後當無法透過單一 cmdlet 本身所提供的第一種 Filter 方式時,我們轉而使用第二種方式,透過 Where-Object 來篩選,而這個篩選的過程則需要用到比較運算式( comparison operator )。


使用比較運算子

在電腦領域中,「比較」就是要把兩個物件或值拿來判斷彼此之間的關係。

透過使用「比較運算子」來指明你想要判斷的關係種類。在簡單的判斷中,結果會是一個布林值( Boolean value ):True 或 False。換言之,判斷出來的關係要嘛是你所指定的那樣,要嘛不是。

PowerShell 提供了一系列的比較運算子,用於比較數值、字串和模式。

常用的比較運算子

  • -eq:等於
  • -ne:不等於
  • -gt:大於
  • -lt:小於
  • -like:匹配字串模式(支援萬用字元)
  • -match:正則表達式匹配

而想要一次比較多項條件時,可使用邏輯運算子( logical operator )

常見的邏輯運算子

  • -and :邏輯「和」。只有當兩個子運算式都為** True** 時,結果才為** True**。
(5 -gt 10) -and (10 -qt 100)

# 第一個子運算式:5 -gt 10,即 5 是否大於 10,結果為 False。
# 第二個子運算式:10 -lt 100,即 10 是否小於 100,結果為 True。
# 整體運算式:False -and True,因為 -and 需要兩個子運算式都為 True,所以結果為 False。

  • -or :邏輯「或」。只要有一個子運算式為** True**,結果就為** True**。
(5 -gt 10) -or (10 -lt 100)

# 第一個子運算式:5 -gt 10,結果為 False。
# 第二個子運算式:10 -lt 100,結果為 True。
# 整體運算式:False -or True,因為 -or 只要有一個子運算式為 True,結果就為 True。
  • -not :邏輯「非」。將布林值取反**,True** 變** False,False** 變** True**。

如果您想要列出所有 以 “Win” 開頭的服務:

Get-Service | Where-Object { -not ($_.Name -like 'Win*') }

注意

  • 不區分大小寫!在比較文字字串時,一個大寫字母被視為與其小寫字母相等。

常見的困惑點

在使用 PowerShell 進行篩選和比較時,可能會遇到一些常見的困惑點。

篩選左移優先

問題

為什麼要優先在左側進行篩選?

解答

  • 提升效率:減少不必要的物件傳遞和處理。
  • 節省資源:降低 CPU 和記憶體的使用。

範例比較

不優化的篩選

Get-Service | Where-Object { $_.Status -eq 'Stopped' }

優化的篩選

Get-Service -Status Stopped

明日主題

Day 14 - 遠端控制:一對一及一對多


上一篇
Day 12 - 使你所見更加美觀:格式化
下一篇
Day 14 - 關於 PowerShell 遠端控制
系列文
《30天挑戰精通 PowerShell:從 Windows Server 到 Azure DevOps 自動化之旅》30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言