當我正準備記下學習Powershell函數(shù)的心得時,突然因為別的事情需要使用計算器。于是我就將就已經(jīng)打開的Powershell控制臺完全了計算。這個時間,我突然想起,忘了把Powersehll的運算符記錄下來。
Powershell有哪些運行符?當然Google有答案,也許Baidu也有答案。不過我決定還是先問Powershell試試。所以我嘗試了這么一條命令:
- PS F:\> help about_operator
嘿,蒙對了,這里果然有Powershell運算符的詳細介紹。
Powershell支持運算符主要有這么幾種類型:
雖然Powershell的幫助文檔里已經(jīng)對運算符進行了很詳細的分類,但是為便于理解不同類型的運算,我還是對它進行了重新分類。
算術運算符就是小學用于四則運算的那些符號:+、-、*、/、(),以及經(jīng)常用在程序設計語言中的幾個運算符:%、++、--。
這些運算符中,+和*都可以用于字符串運算;其中+還可以用于連接數(shù)組和哈希表,*還可以用于復制數(shù)組。不過這些都不屬于算術運算的范疇,所以這里暫時不作說明。
運算符的優(yōu)先級和小學的時候學的一樣,括號優(yōu)先,然后是乘除,最后是加減。這里%和優(yōu)先級和乘除一樣,而++和--的優(yōu)先級需要特別說明。除此之外,還有一些需要特別說明的地方:
1. -,它實際是兩個運算符:它即可以作為單目運算符表示對數(shù)值或變量取負,也可以用作雙目運算符,表示兩個值相減。當-作為取負運算符的時候,它的優(yōu)先級高于乘除和取余。
2. %,這是取余運算符,用法和優(yōu)先級都與/號完全一樣,只是結果不同。/號用于取商,而%號用于取余數(shù)。愛動腦筋的朋友這里會發(fā)現(xiàn)2個問題:
1) /號用于取商,得到的結果是整數(shù)部還是精確的實數(shù)結果呢?
2) %號能取實數(shù)除法的余數(shù)么?
做個實驗就明白了:
- PS F:\> 3 / 2 # 得到的是實數(shù)商
- 1.5
- PS F:\> 3.2 % 2 # 余數(shù)居然可以是小數(shù)呢
- 1.2
- PS F:\>
由于實驗結果對第1)個問題的解答,我們不得不面對第3)個問題:
3) 如果想得到整數(shù)商,該怎么辦?
如果做過C/C++/C#/Java開發(fā),一定會想到一個辦法:強制轉換。Powershell的強制轉換有2種方式,一種是直接類型強制轉換,另一種是通過-as運算符進行轉換
- PS F:\> [int] (3 / 2) # 直接類型強制轉換
- 2
- PS F:\> (3 / 2) -as [int] # -as運算符進行類型轉換
- 2
- PS F:\>
天啊,強制轉換的結果是四舍五入計算的。幸好我們是用3 / 2來做實驗,如果用了4 / 3,你一定會認為這種方法挺有效的。
不過現(xiàn)在我們需要找另一種方法來解決問題——取不大于值的最大整數(shù),用.NET類中Math類的Floor方法可以實現(xiàn)。
- PS F:\> [math]::floor(3 / 2)
- 1
- PS F:\>
但這種方法只對正數(shù)有效。如果是負數(shù),就要用[math]::ceiling了,取不小于參數(shù)值的最小整數(shù)。
3. ++和--,自增和自減運算符。這兩個運算符本來是屬于賦值運算符,因為它們只能對變更進行運算,并將結果回賦給變量。不過很多時候它們也用于算術表達式中,所以就在這里一并說了。了解C/Java語系語法的都明白這兩個運算符的用法,不了解的,做個實驗也就明白了
- PS F:\> $a = 5
- PS F:\> $a++ # $a自已+1,并將結果回賦給自己
- PS F:\> $a
- 6
- PS F:\> $a-- # $a自己-1,并將結果回賦給自己
- PS F:\> $a
- 5
- PS F:\>
++和--運算符在算術表達式中的優(yōu)先級完全取決這兩個運算符相對于它們運算的變量的位置。如果它們用在變量之后,那么它們將在整個表達式的最后進行計算;如果它們用在變量之前,則在整個表達式的最前進行計算,比如
- PS F:\> $a = 5
- PS F:\> 3 + $a++ # 先運算了3+$a(5),之后$a再自加1
- 8
- PS F:\> $a
- 6
- PS F:\> 6 - --$a # $a先自減1,值變?yōu)?之后,再進行6-$a(5)的運算
- 1
- PS F:\> $a
- 5
- PS F:\>
最常見的賦值運算符,當然是=。除此之外還有+=、-=、*=、/=、%=,以及被Powershell單獨列為一類的++和--(這兩個運算符已經(jīng)在上面說過咯)。
=運算符很好理解,就是把右邊的值賦給左邊的變量。其它5個含=號的賦值運算符對C/Java系的同學們來說也不陌生。它們是將符號左邊的變量值,與右邊的表達式結果進行相應的運算(注意=號前面那個符號就是它的運算符)之后,再將結果賦值給左邊的變量。比如
- PS F:\> $a = 5
- PS F:\> $a += 3
- PS F:\> $a
- 8
- PS F:\>
條件運算符就是用于組成條件表達式的運算符。Powershell的比較運算符和邏輯運算符都是條件運算符。它們都有一個共同點:結果一定是布爾值True或者False。
比較運算符包括:-eq(相等)、-ne(不等)、-lt(小于)、-gt(大于)、-le(小于等于)、-ge(大于等于),它們可以用于比較兩個數(shù)值,或者兩個字符串。另外還有一套專門用于比較/匹配字符串的比較運算符,比如-match、-like、-ieq、-ceq等,將在字符串運算符(就是下一節(jié))里進行介紹。
邏輯運算符主要用于連接各條件表達式,這些運算符包括:-and(和/與)、-or(或)、-xor(異或)、-not(非)、!(簡化的-not)。
單的舉兩個例子:
- PS F:\> (2 -lt 3) -and (3.2 -gt 3)
- True
- PS F:\> !(2 -lt 3)
- False
Powershell對字符串的處理功能是非常強大的,這些處理基本上都通過字符串運算符表現(xiàn)出來了。字符串運算符主要包括兩類,一類是用于產(chǎn)生字符串的,另一類是用于比較和匹配字符串的。
1) 比較/匹配類運算符
從這三組共18個比較運算符可以看出來字符串比較類運算符的規(guī)律:有一組默認的,默認的都不區(qū)分大小寫;還有一組帶i前綴的,意思是ignore case,仍然是不區(qū)分大小寫;最后一組帶c前綴,意思是case sensitive,區(qū)分大小寫。
以上所有用于字符串比較/匹配的運算符,用于字符串比較時,返回True或者False。它們也可以用于對字符串數(shù)組進行過濾,并將數(shù)組所有測試值為True的字符串組成一個新的字符串數(shù)組返回。比如
- PS F:\> $a = "James Fancy", "abcdefg", "gfedcba", "ABCDEFG"
- PS F:\> $a[0] -cmatch "a." # 數(shù)組的第1個元素,是個字符串,返回布爾值
- True
- PS F:\> $a -like "a*" # 整個數(shù)組進行匹配,返回匹配成功的
- abcdefg
- ABCDEFG
- PS F:\> $b = $a -like "a*" # 將匹配結果賦值給變量$b
- PS F:\> $b.getType().fullName #查看$b的類型,是數(shù)組類型
- System.Object[]
- PS F:\> $b.length # $b的長度為2
- 2
- PS F:\> $b = $a -clike "a*" # 看看數(shù)組中只有1項匹配的時候會怎么樣
- PS F:\> $b.getType().fullName # $b仍然是數(shù)組
- System.Object[]
- PS F:\> $b.length # $b是長度為1(只有1個元素)的數(shù)組
- 1
- PS F:\>
2) 產(chǎn)生字符串的運算符
+、+=,用于連接字符串。如
- PS F:\> "James" + " Fancy"
- James Fancy
- PS F:\> $a = "Hello "
- PS F:\> $a += "James"
- PS F:\> $a
- Hello James
- PS F:\>
*、*=都可以用于產(chǎn)生重復一定數(shù)量的字符串。比如
- PS F:\> "ABCD" * 5
- ABCDABCDABCDABCDABCD
- PS F:\> $spliter = "-"
- PS F:\> $spliter *= 40
- PS F:\> $spliter
- ----------------------------------------
- PS F:\>
-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
- PS F:\>
-split和-join分別用于拆分字符串(為數(shù)組)和聯(lián)接字符串(從數(shù)組)。-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?
- PS F:\>
-f通過格產(chǎn)生字符串,類似.NET框架中的String.Format函數(shù)。比如
- 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)
- J.Fan; 2011-10-07;HEX: 74CBB1
- PS F:\>
@(),產(chǎn)生數(shù)組對象。如果括號里沒有內(nèi)容,產(chǎn)生一個空數(shù)組。如果括號里有多個元素,用逗號進行分隔——對了,這里用到了所謂的逗號(,)運算符。其實,多個元素的時候,連@()都省了,直接寫列表就是數(shù)組。
..(兩個點號),范圍運算符,產(chǎn)生整型數(shù)組的另一種方式,只需要給定上下限整數(shù),就可以產(chǎn)生一個包含連續(xù)整數(shù)的數(shù)組。
數(shù)組是以0為起始下標的,對數(shù)組元素的訪問是中括號,以及包含在中括號中的下標號。比如
- PS F:\> $a = @(1,2,3,4,5) # 也可以是 $a = 1,2,3,4,5
- PS F:\> $a.length
- 5
- PS F:\> $a[1]
- 2
- PS F:\> @(1..2)
- 1
- 2
- PS F:\> 3..1
- 3
- 2
- 1
- PS F:\>
@{},產(chǎn)生哈希表對象。大括號內(nèi)沒有內(nèi)容,產(chǎn)生一個空的哈希表對象。大括號中是以鍵值對為單位,鍵和值之間用=號分隔。如果大括號里有多個鍵值對,用分號分隔。
對哈希表中元素的訪問也是通過中括號,不過中括號中的是鍵名而不是下標號。如果鍵名是合法的標識符,那么還可以通過“.鍵名”的方式來訪問。比如
- PS F:\> $a = @{abc=1; "bcd"=2; 3="James Fancy"}
- PS F:\> $a["abc"]
- 1
- PS F:\> $a.bcd = "Hello"
- PS F:\> "$($a['bcd']) $($a[3])" # $(...) 表示運算表達式
- Hello James Fancy
- PS F:\>
+和+=,可以聯(lián)接兩個數(shù)組并產(chǎn)生一些新的數(shù)組;它也可以將一個元素聯(lián)連到數(shù)組上。
- PS F:\> @("hello") + "james", "fancy"
- hello
- james
- fancy
- PS F:\> $a = "hello", "james"
- PS F:\> $a += "fancy"
- PS F:\> $a
- hello
- james
- fancy
- PS F:\>
*和*=,將數(shù)組重復指定次數(shù),并將所有這些元素作為一個新的數(shù)組返回。
- PS F:\> "james", "fancy" * 2
- james
- fancy
- james
- fancy
- PS F:\> $a = @("j.fan")
- PS F:\> $a *= 3
- PS F:\> $a
- j.fan
- j.fan
- j.fan
- PS F:\>
-contains, -notcontains,用于判斷數(shù)組中是否有某個數(shù)據(jù),支持i和c前綴用于字符串比較。
- PS F:\> "abc", "bcd" -contains "BCD"
- True
- PS F:\> "abc", "bcd" -ccontains "BCD"
- False
- PS F:\>
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
- PS F:\>
類型運算符一共就3個,兩個用于判斷類型:-is、-isnot;還有一個用于轉換類型:-as。
- PS F:\> 1 -is [int]
- True
- PS F:\> 1 -isnot [int]
- False
- PS F:\> "0xff" -as [int]
- 255
- PS F:\> [int] "0xff" # 強制類型,和上句同樣效果
- 255
- PS F:\>
關于重定向,這是所有控制臺中的一個重要話題,還是找個時間專門來記錄下吧。這次,只把幾個關于重定向的運算符列出來。
&,調(diào)用運算符。如果后面接一個命令,那它和沒帶&符號,直接輸入命令沒啥區(qū)別。但是,如果有一個保存著命令名稱的變量,&就很有用了……還有一點需要注意的是,這個變量只能是命令本身,不能帶參數(shù),不然會出錯的。
- PS F:\> $cmd = "echo Hello James"
- PS F:\> & $cmd # 哇哦,這個會出錯哦
- 無法將“echo Hello James”項識別為 cmdlet、函數(shù)、腳本文件或可運行程序的名稱。請檢查名稱的拼寫,如果
- 包括路徑,請確保路徑正確,然后重試。
- 所在位置 行:1 字符: 2
- + & <<<< $cmd
- + CategoryInfo : ObjectNotFound: (echo Hello James:String) [], CommandNotFoundExcepti
- on
- + FullyQualifiedErrorId : CommandNotFoundException
- PS F:\> $cmd = "echo"
- PS F:\> & $cmd Hello James # 這樣就對啦
- Hello
- James
- PS F:\>
::(雙冒號),靜態(tài)成員運算符。這個其實以之前的示例中已經(jīng)用過了,就是調(diào)用靜態(tài)成員的。比如之前用到的[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:\>
.(點號),訪問對象的成員的運算符。這個也用過很多次了,再舉個例子:
- PS F:\> $r = new-object random
- PS F:\> $r.next() # 獲取一個隨機整數(shù)
- 397489906
- PS F:\> $r.getType().fullName
- System.Random
- PS F:\>
.(點號),還有一個作用,用于獲取來源——就是有點像C/C++中的#include。這個時候它的后面接一個腳本文件,比如
- PS F:\> echo "`$a = `"Hello J.Fan`"" > hello.ps1
- PS F:\> cat .\hello.ps1 # 顯示hello.ps1的內(nèi)容
- $a = "Hello J.Fan"
- PS F:\> .\hello.ps1 # 不用.號調(diào)用腳本。注意:這里的點號是代表當前目錄
- PS F:\> $a
- PS F:\> . .\hello.ps1 # 用.號引入腳本
- PS F:\> $a
- Hello J.Fan
- PS F:\>
總算把運算符搞定了,真沒想到居然這么多!
更多建議: