最近在教育訓練PowerShell,在講到Pipeline的時候,對于我這種長期和資料(資料庫)打交道的人來說,覺得很實用,是以寫此博文,記錄一下。
無論是在Linux中寫Bash腳本還是在Window上寫PowerShell,管道符”|“是一個非常有用的工具。它提供了将前一個指令的輸出作為下一個指令的輸入的功能。在資料進行中,我們也可以使用管道符對資料進行各種操作。
先說導入導出是為了能夠為接下來的資料處理準備資料。在PowerShell中我們也可以通過各種Get-XXX指令獲得各種各樣需要的資料,但是并不是所有作業系統和各個版本的PowerShell都支援某個指令的。比如Get-Volume指令,用于獲得每個磁盤的資訊,但是這個指令不能在Win7下運作,隻能在Win8或Win2012Server下運作。
最常見,最簡單的外部資料源就是CSV檔案了。我們可以使用Export-Csv指令将PowerShell中的對象轉換為CSV格式,持久化到磁盤上。比如我們将目前的所有程序資訊導出為CSV檔案,指令為:
Get-Process | Export-Csv C:\test.csv -Encoding Unicode
(注意,如果是有中文内容建議設定Encoding為Unicode或者UTF8)
Import-Csv指令是導入外部的CSV檔案到記憶體。比較剛才導出的CSV檔案,我們接下來要對這個檔案進行處理。我們可以将檔案的内容儲存到變量$data中。指令為:
$data=Import-Csv C:\test.csv -Encoding Unicode
當然,我們也可以先進行類型轉換,然後儲存。指令為:
$data | ConvertTo-Csv | Out-File C:\test.csv -Encoding utf8
前面我們已經将CSV的内容載入到$data變量中了,那麼如果我們要按照某一個字段排序,可以使用Sort-Object指令。
比如我們要Name這個字段排序,并輸出排序後的結果,那麼指令為:
$data | Sort-Object Name
也可以簡寫為:
$data | Sort Name
如果是需要多個字段排序,那麼可以将字段列在後面,字段之間用逗号隔開。
$data | Sort Name,Handles
如果是逆向排序,那麼需要在字段後面加參數-Descending
$data | Sort Name –Descending
選取相當于SQL中的SELECT指令。對應的PowerShell指令是Select-Object,可以簡寫為Select。該指令後面跟上要選取的列名即可。如果是要選取所有的列,也可以使用*表示。
$data | select Name,VM
選取所有列,那麼指令就是:
$data | select *
如果是隻選取前面幾條資料,那麼可以使用-First參數。比如我們按Handles排序,隻檢視頭10條程序記錄的名字和Handles。指令為:
$data | sort Handles | select Handles,Name -First 10
另外還有參數-Last選取的是最後幾條記錄,-Skip可以選擇跳過一定記錄。
在SELECT的時候,我們可以使用函數對其中的列進行運算,使用的文法是:
@{
n='New Column Name';
e={ $_.xxxCalc }
}
其中的$_就是表示目前的記錄。
比如VM列記錄的是以Byte為機關的資料,我們先建立一列名為”VM(MB)”,其值是換算成MB的結果,那麼我們可以寫為:
$data | select Name,VM,@{n="VM(MB)";e={$_.VM/1MB}}
說度量可能有點不是很清晰,其實就是對應SQL中的聚合函數。比如 SUM, Max,Min之類的,需要使用Measure-Object指令。比如要檢視有多少個程式,最小的Handles和最大的Handles,那麼指令是:
$data | Measure-Object -Property Handles -Minimum -Maximum
既然說到SQL中的聚合函數,那麼自然就會想到另外一個關鍵字Group By。在PowerShell中也有對應的指令Group-Object。如果我們想要按程序的Name進行分組,檢視每個程序名對應的VM總大小。那麼我們可以先按Name進行Group:
$data | Group-Object Name
這時我們可以看到系統傳回的結果有3列:Count,Name,Group。而我們要進行聚合的VM值是在Group中。這時需要用到前面提到的Select指令。
$data | Group-Object Name | select Name,Count,@{n="TotalVM";e={($_.Group | Measure-Object -Property VM -Sum).Sum}}
過濾相當于SLQ中的Where語句,在PowerShell中使用Where-Object指令。可以簡寫為Where,甚至可以簡寫為”?”。在普通程式裡面我們遇到的比較運算和邏輯運算在PowerShell中有所不同,是這樣的參數:
Comparison
Case-InSensitive
Case-sensitive
Equality
-eq
-ceq
Inequality
-ne
-cne
Greater than
-gt
-cgt
Less than
-lt
-clt
Greater than or equal to
-ge
-cge
Less than or equal to
-le
-cle
Wildcard equality
-like
-clike
-and 和-or用于邏輯運算。
仍然以前面load的$data為例,我們要檢視以W開頭的程序的Handles和Name,那麼指令為:
$data | ?{ $_.Name -like 'W*'}| select Handles,Name
如果是多個條件,既要以w開頭,還要VM大于100M的程序,那麼指令為:
$data | ?{ $_.Name -like 'W*' -and $_.VM -gt 100MB}| select Handles,Name,VM
枚舉相當于C#中的Foreach函數,或者說是SQL中的遊标,對于每一行資料,都進行一個運算或者函數處理。在PowerShell中對應的指令是ForEach-Object,可以簡寫為ForEach,還可以進一步簡寫為”%“。
比如我們要将VM改為MB為機關,可以對每一行資料進行運算:
$data | % {$_.VM=$_.VM/1MB}
運作該指令後我們再檢視$data就會發現VM列已經改變了。
另外對于Foreach指令,還有兩個比較有用的參數-Begin –End,用于在做For循環之前調用和循環結束後調用。
比如我們想把某一列寫入一個檔案,我們可以在-Begin時建立檔案,記錄開始的時間,然後Foreach中Append内容到檔案,最後把結束時間寫入:
$data | % -Begin { Get-Date | Out-File C:\test.txt } -Process { $_.Name | Out-File C:\test.txt -Append} -End { Get-Date | Out-File C:\test.txt -Append}
本文轉自深藍居部落格園部落格,原文連結:http://www.cnblogs.com/studyzy/p/4518807.html,如需轉載請自行聯系原作者