天天看點

Powershell學習筆記——運算符

 當我正準備記下學習Powershell函數的心得時,突然因為别的事情需要使用電腦。于是我就将就已經打開的Powershell控制台完全了計算。這個時間,我突然想起,忘了把Powersehll的運算符記錄下來。

  Powershell有哪些運作符?當然Google有答案,也許Baidu也有答案。不過我決定還是先問Powershell試試。是以我嘗試了這麼一條指令:

PS F:\> help about_operator 

  嘿,蒙對了,這裡果然有Powershell運算符的詳細介紹。

  Powershell支援運算符主要有這麼幾種類型:

  √ 算術運算符:用于進行數值計算

  √ 指派運算符:給變量指派,或者計算後指派

  √ 比較運算符:條件運算符的其中一類,用于比較值或對象的大小

  √ 邏輯運算符:條件運算符的另一類,用于連接配接多個條件表達式

  √ 重定向運算符:用于重定向的運算符,詳情參考about_redirection

  √ 拆分/聯接運算符:字元串運算符的一類,用于對字元串進行拆分和聯接

  √ 類型運算符:判斷或更改對象的類型

  √ 一進制運算符:就是++和--啦

  √ 特殊運算符:其它比較特殊的運算符

  雖然Powershell的幫助文檔裡已經對運算符進行了很詳細的分類,但是為便于了解不同類型的運算,我還是對它進行了重新分類。

  算術運算符就是國小用于四則運算的那些符号:+、-、*、/、(),以及經常用在程式設計語言中的幾個運算符:%、++、--。

  這些運算符中,+和*都可以用于字元串運算;其中+還可以用于連接配接數組和哈希表,*還可以用于複制數組。不過這些都不屬于算術運算的範疇,是以這裡暫時不作說明。

  運算符的優先級和國小的時候學的一樣,括号優先,然後是乘除,最後是加減。這裡%和優先級和乘除一樣,而++和--的優先級需要特别說明。除此之外,還有一些需要特别說明的地方:

  1. -,它實際是兩個運算符:它即可以作為單目運算符表示對數值或變量取負,也可以用作雙目運算符,表示兩個值相減。當-作為取負運算符的時候,它的優先級高于乘除和取餘。

  2. %,這是取餘運算符,用法和優先級都與/号完全一樣,隻是結果不同。/号用于取商,而%号用于取餘數。愛動腦筋的朋友這裡會發現2個問題:

1) /号用于取商,得到的結果是整數部還是精确的實數結果呢?

2) %号能取實數除法的餘數麼?

做個實驗就明白了:

PS F:\> 3 / 2 # 得到的是實數商 

1.5 

PS F:\> 3.2 % 2 # 餘數居然可以是小數呢 

1.2 

PS F:\> 

  由于實驗結果對第1)個問題的解答,我們不得不面對第3)個問題:

3) 如果想得到整數商,該怎麼辦?

如果做過C/C++/C#/Java開發,一定會想到一個辦法:強制轉換。Powershell的強制轉換有2種方式,一種是直接類型強制轉換,另一種是通過-as運算符進行轉換

PS F:\> [int] (3 / 2) # 直接類型強制轉換 

PS F:\> (3 / 2) -as [int] # -as運算符進行類型轉換 

  天啊,強制轉換的結果是四舍五入計算的。幸好我們是用3 / 2來做實驗,如果用了4 / 3,你一定會認為這種方法挺有效的。

不過現在我們需要找另一種方法來解決問題——取不大于值的最大整數,用.NET類中Math類的Floor方法可以實作。

PS F:\> [math]::floor(3 / 2) 

  但這種方法隻對正數有效。如果是負數,就要用[math]::ceiling了,取不小于參數值的最小整數。

  3. ++和--,自增和自減運算符。這兩個運算符本來是屬于指派運算符,因為它們隻能對變更進行運算,并将結果回賦給變量。不過很多時候它們也用于算術表達式中,是以就在這裡一并說了。了解C/Java語系文法的都明白這兩個運算符的用法,不了解的,做個實驗也就明白了

PS F:\> $a = 5 

PS F:\> $a++ # $a自已+1,并将結果回賦給自己 

PS F:\> $a 

PS F:\> $a-- # $a自己-1,并将結果回賦給自己 

  ++和--運算符在算術表達式中的優先級完全取決這兩個運算符相對于它們運算的變量的位置。如果它們用在變量之後,那麼它們将在整個表達式的最後進行計算;如果它們用在變量之前,則在整個表達式的最前進行計算,比如

PS F:\> 3 + $a++ # 先運算了3+$a(5),之後$a再自加1 

PS F:\> 6 - --$a # $a先自減1,值變為5之後,再進行6-$a(5)的運算 

  最常見的指派運算符,當然是=。除此之外還有+=、-=、*=、/=、%=,以及被Powershell單獨列為一類的++和--(這兩個運算符已經在上面說過咯)。

  =運算符很好了解,就是把右邊的值賦給左邊的變量。其它5個含=号的指派運算符對C/Java系的同學們來說也不陌生。它們是将符号左邊的變量值,與右邊的表達式結果進行相應的運算(注意=号前面那個符号就是它的運算符)之後,再将結果指派給左邊的變量。比如

PS F:\> $a += 3 

  條件運算符就是用于組成條件表達式的運算符。Powershell的比較運算符和邏輯運算符都是條件運算符。它們都有一個共同點:結果一定是布爾值True或者False。

  比較運算符包括:-eq(相等)、-ne(不等)、-lt(小于)、-gt(大于)、-le(小于等于)、-ge(大于等于),它們可以用于比較兩個數值,或者兩個字元串。另外還有一套專門用于比較/比對字元串的比較運算符,比如-match、-like、-ieq、-ceq等,将在字元串運算符(就是下一節)裡進行介紹。

  邏輯運算符主要用于連接配接各條件表達式,這些運算符包括:-and(和/與)、-or(或)、-xor(異或)、-not(非)、!(簡化的-not)。

  單的舉兩個例子:

PS F:\> (2 -lt 3) -and (3.2 -gt 3) 

True 

PS F:\> !(2 -lt 3) 

False 

  Powershell對字元串的處理功能是非常強大的,這些處理基本上都通過字元串運算符表現出來了。字元串運算符主要包括兩類,一類是用于産生字元串的,另一類是用于比較和比對字元串的。

  1) 比較/比對類運算符

  -eq、-ne、-lt、-gt、-le、-ge,比較字元串,不區分大小寫

  -ieq、-ine、-ilt、-igt、-ile、-ige,比較字元串,不區分大小寫

  -eq、-ne、-lt、-gt、-le、-ge,比較字元串,區分大小寫

  從這三組共18個比較運算符可以看出來字元串比較類運算符的規律:有一組預設的,預設的都不區分大小寫;還有一組帶i字首的,意思是ignore case,仍然是不區分大小寫;最後一組帶c字首,意思是case sensitive,區分大小寫。

  -like、-notlike,使用通配符(*)進行比對,支援i和c字首。

  -match、-notmatch,使用正規表達式進行比對,支援i和c字首。

  以上所有用于字元串比較/比對的運算符,用于字元串比較時,傳回True或者False。它們也可以用于對字元串數組進行過濾,并将數組所有測試值為True的字元串組成一個新的字元串數組傳回。比如

PS F:\> $a = "James Fancy", "abcdefg", "gfedcba", "ABCDEFG" 

PS F:\> $a[0] -cmatch "a." # 數組的第1個元素,是個字元串,傳回布爾值 

PS F:\> $a -like "a*" # 整個數組進行比對,傳回比對成功的 

abcdefg 

ABCDEFG 

PS F:\> $b = $a -like "a*" # 将比對結果指派給變量$b 

PS F:\> $b.getType().fullName #檢視$b的類型,是數組類型 

System.Object[] 

PS F:\> $b.length # $b的長度為2 

PS F:\> $b = $a -clike "a*" # 看看數組中隻有1項比對的時候會怎麼樣 

PS F:\> $b.getType().fullName # $b仍然是數組 

PS F:\> $b.length # $b是長度為1(隻有1個元素)的數組 

  2) 産生字元串的運算符

  +、+=,用于連接配接字元串。如

PS F:\> "James" + " Fancy" 

James Fancy 

PS F:\> $a = "Hello " 

PS F:\> $a += "James" 

Hello James 

  *、*=都可以用于産生重複一定數量的字元串。比如

PS F:\> "ABCD" * 5 

ABCDABCDABCDABCDABCD 

PS F:\> $spliter = "-" 

PS F:\> $spliter *= 40 

PS F:\> $spliter 

---------------------------------------- 

  -replace用于替換掉字元串中的比對項,并傳回新的字元串,支援i和c字首。-replace可以按正規表達式進行比對。如

PS F:\> $a = "Hello Mr. James" 

PS F:\> $a -replace "james", "Fancy" 

Hello Mr. Fancy 

PS F:\> $a = "Hello Mr. James and Mr. Fancy" 

PS F:\> $a -replace "Mr.\s*(.*?)\b", "$1" # -replace可以按正規表達式比對 

Hello James and Fancy 

  -split和-join分别用于拆分字元串(為數組)和聯接字元串(從數組)。-split支援通過正規表達式比對分隔符。如

PS F:\> $a = "Hello, James Fancy. How are you?" 

PS F:\> $b = $a -split "[,\s\.]+" 

PS F:\> $b 

Hello 

James 

Fancy 

How 

are 

you? 

PS F:\> $b -join ";" 

Hello;James;Fancy;How;are;you? 

  -f通過格産生字元串,類似.NET架構中的String.Format函數。比如

PS F:\> "{0}; {1:yyyy-MM-dd};HEX: {2:X4}" -f "J.Fan", $(get-date), 7654321 

J.Fan; 2011-10-07;HEX: 74CBB1 

PS F:\> [string]::format("{0}; {1:yyyy-MM-dd};HEX: {2:X4}", "J.Fan", $(get-date), 7654321) 

  @(),産生數組對象。如果括号裡沒有内容,産生一個空數組。如果括号裡有多個元素,用逗号進行分隔——對了,這裡用到了所謂的逗号(,)運算符。其實,多個元素的時候,連@()都省了,直接寫清單就是數組。

  ..(兩個點号),範圍運算符,産生整型數組的另一種方式,隻需要給定上下限整數,就可以産生一個包含連續整數的數組。

  數組是以0為起始下标的,對數組元素的通路是中括号,以及包含在中括号中的下标号。比如

PS F:\> $a = @(1,2,3,4,5) # 也可以是 $a = 1,2,3,4,5 

PS F:\> $a.length 

PS F:\> $a[1] 

PS F:\> @(1..2) 

PS F:\> 3..1 

  @{},産生哈希表對象。大括号内沒有内容,産生一個空的哈希表對象。大括号中是以鍵值對為機關,鍵和值之間用=号分隔。如果大括号裡有多個鍵值對,用分号分隔。

  對哈希表中元素的通路也是通過中括号,不過中括号中的是鍵名而不是下标号。如果鍵名是合法的辨別符,那麼還可以通過“.鍵名”的方式來通路。比如

PS F:\> $a = @{abc=1; "bcd"=2; 3="James Fancy"} 

PS F:\> $a["abc"] 

PS F:\> $a.bcd = "Hello" 

PS F:\> "$($a['bcd']) $($a[3])" # $(...) 表示運算表達式 

Hello James Fancy 

  +和+=,可以聯接兩個數組并産生一些新的數組;它也可以将一個元素聯連到數組上。

PS F:\> @("hello") + "james", "fancy" 

hello 

james 

fancy 

PS F:\> $a = "hello", "james" 

PS F:\> $a += "fancy" 

  *和*=,将數組重複指定次數,并将所有這些元素作為一個新的數組傳回。

PS F:\> "james", "fancy" * 2 

PS F:\> $a = @("j.fan") 

PS F:\> $a *= 3 

j.fan 

  -contains, -notcontains,用于判斷數組中是否有某個資料,支援i和c字首用于字元串比較。

PS F:\> "abc", "bcd" -contains "BCD" 

PS F:\> "abc", "bcd" -ccontains "BCD" 

  Powershell有4個位運算符,-band(按位與)、-bor(按位或)、-bxor(按位異或)、-bnot(按位取反)。很不幸,沒有移位運算符。

PS F:\> (0x6b -band 0xf0).toString("X") 

60 

PS F:\> (0x6b -bor 0x0f).toString("X") 

6F 

PS F:\> (0x6b -bxor 0xff).toString("X") 

94 

PS F:\> (-bnot 0x6b).toString("X") 

FFFFFF94 

  類型運算符一共就3個,兩個用于判斷類型:-is、-isnot;還有一個用于轉換類型:-as。

PS F:\> 1 -is [int] 

PS F:\> 1 -isnot [int] 

PS F:\> "0xff" -as [int] 

255 

PS F:\> [int] "0xff" # 強制類型,和上句同樣效果 

  關于重定向,這是所有控制台中的一個重要話題,還是找個時間專門來記錄下吧。這次,隻把幾個關于重定向的運算符列出來。

  >,将輸出發送到指定檔案。

  >>,将輸出追加到指定檔案的内容。

  2>,将錯誤發送到指定檔案。

  2>>,将錯誤追加到指定檔案的内容。

  2>&1,将錯誤發送到成功輸出流。

  &,調用運算符。如果後面接一個指令,那它和沒帶&符号,直接輸入指令沒啥差別。但是,如果有一個儲存着指令名稱的變量,&就很有用了……還有一點需要注意的是,這個變量隻能是指令本身,不能帶參數,不然會出錯的。

PS F:\> $cmd = "echo Hello James" 

PS F:\> & $cmd # 哇哦,這個會出錯哦 

無法将“echo Hello James”項識别為 cmdlet、函數、腳本檔案或可運作程式的名稱。請檢查名稱的拼寫,如果 

包括路徑,請確定路徑正确,然後重試。 

所在位置 行:1 字元: 2 

+ & <<<< $cmd 

+ CategoryInfo : ObjectNotFound: (echo Hello James:String) [], CommandNotFoundExcepti 

on 

+ FullyQualifiedErrorId : CommandNotFoundException 

PS F:\> $cmd = "echo" 

PS F:\> & $cmd Hello James # 這樣就對啦 

  ::(雙冒号),靜态成員運算符。這個其實以之前的示例中已經用過了,就是調用靜态成員的。比如之前用到的[string]::format,[math]::floor等。再比如

PS F:\> [system.text.encoding]::utf8.toString() 

System.Text.UTF8Encoding 

PS F:\> [guid]::newGuid() 

Guid 

---- 

76e2b9ed-71f7-4b91-89c6-1c329df82e96 

  .(點号),通路對象的成員的運算符。這個也用過很多次了,再舉個例子:

PS F:\> $r = new-object random 

PS F:\> $r.next() # 擷取一個随機整數 

397489906 

PS F:\> $r.getType().fullName 

System.Random 

  .(點号),還有一個作用,用于擷取來源——就是有點像C/C++中的#include。這個時候它的後面接一個腳本檔案,比如

PS F:\> echo "`$a = `"Hello J.Fan`"" > hello.ps1 

PS F:\> cat .\hello.ps1 # 顯示hello.ps1的内容 

$a = "Hello J.Fan" 

PS F:\> .\hello.ps1 # 不用.号調用腳本。注意:這裡的點号是代表目前目錄 

PS F:\> . .\hello.ps1 # 用.号引入腳本 

Hello J.Fan 

  總算把運算符搞定了,真沒想到居然這麼多!

本文轉自邊城__ 51CTO部落格,原文連結:http://blog.51cto.com/jamesfancy/682246,如需轉載請自行聯系原作者