使用管道符在PowerShell中進行各種數據操作


最近在培訓PowerShell,在講到Pipeline的時候,對於我這種長期和數據(數據庫)打交道的人來說,覺得很實用,所以寫此博文,記錄一下。

無論是在Linux中寫Bash腳本還是在Window上寫PowerShell,管道符”|“是一個非常有用的工具。它提供了將前一個命令的輸出作為下一個命令的輸入的功能。在數據處理中,我們也可以使用管道符對數據進行各種操作。

Import&Export導入導出

先說導入導出是為了能夠為接下來的數據處理准備數據。在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

Sorting排序

前面我們已經將CSV的內容載入到$data變量中了,那么如果我們要按照某一個字段排序,可以使用Sort-Object命令。

比如我們要Name這個字段排序,並輸出排序后的結果,那么命令為:

$data | Sort-Object Name

也可以簡寫為:

$data | Sort Name

如果是需要多個字段排序,那么可以將字段列在后面,字段之間用逗號隔開。

$data | Sort Name,Handles

如果是逆向排序,那么需要在字段后面加參數-Descending

$data | Sort Name –Descending

Selecting選取

選取相當於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可以選擇跳過一定記錄。

Calculate計算列

在SELECT的時候,我們可以使用函數對其中的列進行運算,使用的語法是:

@{ 
  n='New Column Name'; 
  e={  $_.xxxCalc } 
}

其中的$_就是表示當前的記錄。

比如VM列記錄的是以Byte為單位的數據,我們先新建一列名為”VM(MB)”,其值是換算成MB的結果,那么我們可以寫為:

$data | select Name,VM,@{n= " VM(MB) ";e={ $_.VM/1MB}} 

Measuring度量

說度量可能有點不是很清晰,其實就是對應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}}

Filter過濾

過濾相當於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

Enumeration枚舉

枚舉相當於C#中的Foreach函數,或者說是SQL中的游標,對於每一行數據,都進行一個運算或者函數處理。在PowerShell中對應的命令是ForEach-Object,可以簡寫為ForEach,還可以進一步簡寫為”%“。

比如我們要將VM改為MB為單位,可以對每一行數據進行運算:

$data | % { $_.VM= $_.VM/1MB}

運行該命令后我們再查看$data就會發現VM列已經改變了。

$data | select Name,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}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM