Powershell學(xué)習(xí)筆記——運(yùn)算符

2018-06-09 09:57 更新

  當(dāng)我正準(zhǔn)備記下學(xué)習(xí)Powershell函數(shù)的心得時(shí),突然因?yàn)閯e的事情需要使用計(jì)算器。于是我就將就已經(jīng)打開(kāi)的Powershell控制臺(tái)完全了計(jì)算。這個(gè)時(shí)間,我突然想起,忘了把Powersehll的運(yùn)算符記錄下來(lái)。

Powersehll有哪些運(yùn)算符

  Powershell有哪些運(yùn)行符?當(dāng)然Google有答案,也許Baidu也有答案。不過(guò)我決定還是先問(wèn)Powershell試試。所以我嘗試了這么一條命令:

  1. PS F:\> help about_operator 

  嘿,蒙對(duì)了,這里果然有Powershell運(yùn)算符的詳細(xì)介紹。

  Powershell支持運(yùn)算符主要有這么幾種類(lèi)型:

  √ 算術(shù)運(yùn)算符:用于進(jìn)行數(shù)值計(jì)算
  √ 賦值運(yùn)算符:給變量賦值,或者計(jì)算后賦值
  √ 比較運(yùn)算符:條件運(yùn)算符的其中一類(lèi),用于比較值或?qū)ο蟮拇笮?/div>
  √ 邏輯運(yùn)算符:條件運(yùn)算符的另一類(lèi),用于連接多個(gè)條件表達(dá)式
  √ 重定向運(yùn)算符:用于重定向的運(yùn)算符,詳情參考about_redirection
  √ 拆分/聯(lián)接運(yùn)算符:字符串運(yùn)算符的一類(lèi),用于對(duì)字符串進(jìn)行拆分和聯(lián)接
  √ 類(lèi)型運(yùn)算符:判斷或更改對(duì)象的類(lèi)型
  √ 一元運(yùn)算符:就是++和--啦
  √ 特殊運(yùn)算符:其它比較特殊的運(yùn)算符

  雖然Powershell的幫助文檔里已經(jīng)對(duì)運(yùn)算符進(jìn)行了很詳細(xì)的分類(lèi),但是為便于理解不同類(lèi)型的運(yùn)算,我還是對(duì)它進(jìn)行了重新分類(lèi)。

1. 算術(shù)運(yùn)算符

  算術(shù)運(yùn)算符就是小學(xué)用于四則運(yùn)算的那些符號(hào):+、-、*、/、(),以及經(jīng)常用在程序設(shè)計(jì)語(yǔ)言中的幾個(gè)運(yùn)算符:%、++、--。

  這些運(yùn)算符中,+和*都可以用于字符串運(yùn)算;其中+還可以用于連接數(shù)組和哈希表,*還可以用于復(fù)制數(shù)組。不過(guò)這些都不屬于算術(shù)運(yùn)算的范疇,所以這里暫時(shí)不作說(shuō)明。

  運(yùn)算符的優(yōu)先級(jí)和小學(xué)的時(shí)候?qū)W的一樣,括號(hào)優(yōu)先,然后是乘除,最后是加減。這里%和優(yōu)先級(jí)和乘除一樣,而++和--的優(yōu)先級(jí)需要特別說(shuō)明。除此之外,還有一些需要特別說(shuō)明的地方:

  1. -,它實(shí)際是兩個(gè)運(yùn)算符:它即可以作為單目運(yùn)算符表示對(duì)數(shù)值或變量取負(fù),也可以用作雙目運(yùn)算符,表示兩個(gè)值相減。當(dāng)-作為取負(fù)運(yùn)算符的時(shí)候,它的優(yōu)先級(jí)高于乘除和取余。

  2. %,這是取余運(yùn)算符,用法和優(yōu)先級(jí)都與/號(hào)完全一樣,只是結(jié)果不同。/號(hào)用于取商,而%號(hào)用于取余數(shù)。愛(ài)動(dòng)腦筋的朋友這里會(huì)發(fā)現(xiàn)2個(gè)問(wèn)題:
1) /號(hào)用于取商,得到的結(jié)果是整數(shù)部還是精確的實(shí)數(shù)結(jié)果呢?
2) %號(hào)能取實(shí)數(shù)除法的余數(shù)么?
做個(gè)實(shí)驗(yàn)就明白了:

  1. PS F:\> 3 / 2 # 得到的是實(shí)數(shù)商 
  2. 1.5 
  3. PS F:\> 3.2 % 2 # 余數(shù)居然可以是小數(shù)呢 
  4. 1.2 
  5. PS F:\> 

  由于實(shí)驗(yàn)結(jié)果對(duì)第1)個(gè)問(wèn)題的解答,我們不得不面對(duì)第3)個(gè)問(wèn)題:
3) 如果想得到整數(shù)商,該怎么辦?
如果做過(guò)C/C++/C#/Java開(kāi)發(fā),一定會(huì)想到一個(gè)辦法:強(qiáng)制轉(zhuǎn)換。Powershell的強(qiáng)制轉(zhuǎn)換有2種方式,一種是直接類(lèi)型強(qiáng)制轉(zhuǎn)換,另一種是通過(guò)-as運(yùn)算符進(jìn)行轉(zhuǎn)換

  1. PS F:\> [int] (3 / 2) # 直接類(lèi)型強(qiáng)制轉(zhuǎn)換 
  2. PS F:\> (3 / 2) -as [int] # -as運(yùn)算符進(jìn)行類(lèi)型轉(zhuǎn)換 
  3. PS F:\> 

  天啊,強(qiáng)制轉(zhuǎn)換的結(jié)果是四舍五入計(jì)算的。幸好我們是用3 / 2來(lái)做實(shí)驗(yàn),如果用了4 / 3,你一定會(huì)認(rèn)為這種方法挺有效的。
不過(guò)現(xiàn)在我們需要找另一種方法來(lái)解決問(wèn)題——取不大于值的最大整數(shù),用.NET類(lèi)中Math類(lèi)的Floor方法可以實(shí)現(xiàn)。

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

  但這種方法只對(duì)正數(shù)有效。如果是負(fù)數(shù),就要用[math]::ceiling了,取不小于參數(shù)值的最小整數(shù)。

  3. ++和--,自增和自減運(yùn)算符。這兩個(gè)運(yùn)算符本來(lái)是屬于賦值運(yùn)算符,因?yàn)樗鼈冎荒軐?duì)變更進(jìn)行運(yùn)算,并將結(jié)果回賦給變量。不過(guò)很多時(shí)候它們也用于算術(shù)表達(dá)式中,所以就在這里一并說(shuō)了。了解C/Java語(yǔ)系語(yǔ)法的都明白這兩個(gè)運(yùn)算符的用法,不了解的,做個(gè)實(shí)驗(yàn)也就明白了

  1. PS F:\> $a = 5 
  2. PS F:\> $a++ # $a自已+1,并將結(jié)果回賦給自己 
  3. PS F:\> $a 
  4. PS F:\> $a-- # $a自己-1,并將結(jié)果回賦給自己 
  5. PS F:\> $a 
  6. PS F:\> 

  ++和--運(yùn)算符在算術(shù)表達(dá)式中的優(yōu)先級(jí)完全取決這兩個(gè)運(yùn)算符相對(duì)于它們運(yùn)算的變量的位置。如果它們用在變量之后,那么它們將在整個(gè)表達(dá)式的最后進(jìn)行計(jì)算;如果它們用在變量之前,則在整個(gè)表達(dá)式的最前進(jìn)行計(jì)算,比如

  1. PS F:\> $a = 5 
  2. PS F:\> 3 + $a++ # 先運(yùn)算了3+$a(5),之后$a再自加1 
  3. PS F:\> $a 
  4. PS F:\> 6 - --$a # $a先自減1,值變?yōu)?之后,再進(jìn)行6-$a(5)的運(yùn)算 
  5. PS F:\> $a 
  6. PS F:\> 

2. 賦值運(yùn)算符

  最常見(jiàn)的賦值運(yùn)算符,當(dāng)然是=。除此之外還有+=、-=、*=、/=、%=,以及被Powershell單獨(dú)列為一類(lèi)的++和--(這兩個(gè)運(yùn)算符已經(jīng)在上面說(shuō)過(guò)咯)。

  =運(yùn)算符很好理解,就是把右邊的值賦給左邊的變量。其它5個(gè)含=號(hào)的賦值運(yùn)算符對(duì)C/Java系的同學(xué)們來(lái)說(shuō)也不陌生。它們是將符號(hào)左邊的變量值,與右邊的表達(dá)式結(jié)果進(jìn)行相應(yīng)的運(yùn)算(注意=號(hào)前面那個(gè)符號(hào)就是它的運(yùn)算符)之后,再將結(jié)果賦值給左邊的變量。比如

  1. PS F:\> $a = 5 
  2. PS F:\> $a += 3 
  3. PS F:\> $a 
  4. PS F:\> 

3. 條件運(yùn)算符

  條件運(yùn)算符就是用于組成條件表達(dá)式的運(yùn)算符。Powershell的比較運(yùn)算符和邏輯運(yùn)算符都是條件運(yùn)算符。它們都有一個(gè)共同點(diǎn):結(jié)果一定是布爾值True或者False。

  比較運(yùn)算符包括:-eq(相等)、-ne(不等)、-lt(小于)、-gt(大于)、-le(小于等于)、-ge(大于等于),它們可以用于比較兩個(gè)數(shù)值,或者兩個(gè)字符串。另外還有一套專(zhuān)門(mén)用于比較/匹配字符串的比較運(yùn)算符,比如-match、-like、-ieq、-ceq等,將在字符串運(yùn)算符(就是下一節(jié))里進(jìn)行介紹。

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

  單的舉兩個(gè)例子:

  1. PS F:\> (2 -lt 3) -and (3.2 -gt 3) 
  2. True 
  3. PS F:\> !(2 -lt 3) 
  4. False 

4. 字符串運(yùn)算符

  Powershell對(duì)字符串的處理功能是非常強(qiáng)大的,這些處理基本上都通過(guò)字符串運(yùn)算符表現(xiàn)出來(lái)了。字符串運(yùn)算符主要包括兩類(lèi),一類(lèi)是用于產(chǎn)生字符串的,另一類(lèi)是用于比較和匹配字符串的。

  1) 比較/匹配類(lèi)運(yùn)算符

  -eq、-ne、-lt、-gt、-le、-ge,比較字符串,不區(qū)分大小寫(xiě)
  -ieq、-ine、-ilt、-igt、-ile、-ige,比較字符串,不區(qū)分大小寫(xiě)
  -eq、-ne、-lt、-gt、-le、-ge,比較字符串,區(qū)分大小寫(xiě)

  從這三組共18個(gè)比較運(yùn)算符可以看出來(lái)字符串比較類(lèi)運(yùn)算符的規(guī)律:有一組默認(rèn)的,默認(rèn)的都不區(qū)分大小寫(xiě);還有一組帶i前綴的,意思是ignore case,仍然是不區(qū)分大小寫(xiě);最后一組帶c前綴,意思是case sensitive,區(qū)分大小寫(xiě)。

  -like、-notlike,使用通配符(*)進(jìn)行匹配,支持i和c前綴。
  -match、-notmatch,使用正則表達(dá)式進(jìn)行匹配,支持i和c前綴。

  以上所有用于字符串比較/匹配的運(yùn)算符,用于字符串比較時(shí),返回True或者False。它們也可以用于對(duì)字符串?dāng)?shù)組進(jìn)行過(guò)濾,并將數(shù)組所有測(cè)試值為T(mén)rue的字符串組成一個(gè)新的字符串?dāng)?shù)組返回。比如

  1. PS F:\> $a = "James Fancy", "abcdefg", "gfedcba", "ABCDEFG" 
  2. PS F:\> $a[0] -cmatch "a." # 數(shù)組的第1個(gè)元素,是個(gè)字符串,返回布爾值 
  3. True 
  4. PS F:\> $a -like "a*" # 整個(gè)數(shù)組進(jìn)行匹配,返回匹配成功的 
  5. abcdefg 
  6. ABCDEFG 
  7. PS F:\> $b = $a -like "a*" # 將匹配結(jié)果賦值給變量$b 
  8. PS F:\> $b.getType().fullName #查看$b的類(lèi)型,是數(shù)組類(lèi)型 
  9. System.Object[] 
  10. PS F:\> $b.length # $b的長(zhǎng)度為2 
  11. PS F:\> $b = $a -clike "a*" # 看看數(shù)組中只有1項(xiàng)匹配的時(shí)候會(huì)怎么樣 
  12. PS F:\> $b.getType().fullName # $b仍然是數(shù)組 
  13. System.Object[] 
  14. PS F:\> $b.length # $b是長(zhǎng)度為1(只有1個(gè)元素)的數(shù)組 
  15. PS F:\> 

  2) 產(chǎn)生字符串的運(yùn)算符

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

  1. PS F:\> "James" + " Fancy" 
  2. James Fancy 
  3. PS F:\> $a = "Hello " 
  4. PS F:\> $a += "James" 
  5. PS F:\> $a 
  6. Hello James 
  7. PS F:\> 

  *、*=都可以用于產(chǎn)生重復(fù)一定數(shù)量的字符串。比如

  1. PS F:\> "ABCD" * 5 
  2. ABCDABCDABCDABCDABCD 
  3. PS F:\> $spliter = "-" 
  4. PS F:\> $spliter *= 40 
  5. PS F:\> $spliter 
  6. ---------------------------------------- 
  7. PS F:\> 

  -replace用于替換掉字符串中的匹配項(xiàng),并返回新的字符串,支持i和c前綴。-replace可以按正則表達(dá)式進(jìn)行匹配。如

  1. PS F:\> $a = "Hello Mr. James" 
  2. PS F:\> $a -replace "james", "Fancy" 
  3. Hello Mr. Fancy 
  4. PS F:\> $a = "Hello Mr. James and Mr. Fancy" 
  5. PS F:\> $a -replace "Mr.\s*(.*?)\b", "$1" # -replace可以按正則表達(dá)式匹配 
  6. Hello James and Fancy 
  7. PS F:\> 

  -split和-join分別用于拆分字符串(為數(shù)組)和聯(lián)接字符串(從數(shù)組)。-split支持通過(guò)正則表達(dá)式匹配分隔符。如

  1. PS F:\> $a = "Hello, James Fancy. How are you?" 
  2. PS F:\> $b = $a -split "[,\s\.]+" 
  3. PS F:\> $b 
  4. Hello 
  5. James 
  6. Fancy 
  7. How 
  8. are 
  9. you? 
  10. PS F:\> $b -join ";" 
  11. Hello;James;Fancy;How;are;you? 
  12. PS F:\> 

  -f通過(guò)格產(chǎn)生字符串,類(lèi)似.NET框架中的String.Format函數(shù)。比如

  1. PS F:\> "{0}; {1:yyyy-MM-dd};HEX: {2:X4}" -f "J.Fan", $(get-date), 7654321 
  2. J.Fan; 2011-10-07;HEX: 74CBB1 
  3. PS F:\> [string]::format("{0}; {1:yyyy-MM-dd};HEX: {2:X4}", "J.Fan", $(get-date), 7654321) 
  4. J.Fan; 2011-10-07;HEX: 74CBB1 
  5. PS F:\> 

5. 數(shù)組和哈希表運(yùn)算符

  @(),產(chǎn)生數(shù)組對(duì)象。如果括號(hào)里沒(méi)有內(nèi)容,產(chǎn)生一個(gè)空數(shù)組。如果括號(hào)里有多個(gè)元素,用逗號(hào)進(jìn)行分隔——對(duì)了,這里用到了所謂的逗號(hào)(,)運(yùn)算符。其實(shí),多個(gè)元素的時(shí)候,連@()都省了,直接寫(xiě)列表就是數(shù)組。

  ..(兩個(gè)點(diǎn)號(hào)),范圍運(yùn)算符,產(chǎn)生整型數(shù)組的另一種方式,只需要給定上下限整數(shù),就可以產(chǎn)生一個(gè)包含連續(xù)整數(shù)的數(shù)組。

  數(shù)組是以0為起始下標(biāo)的,對(duì)數(shù)組元素的訪問(wèn)是中括號(hào),以及包含在中括號(hào)中的下標(biāo)號(hào)。比如

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

  @{},產(chǎn)生哈希表對(duì)象。大括號(hào)內(nèi)沒(méi)有內(nèi)容,產(chǎn)生一個(gè)空的哈希表對(duì)象。大括號(hào)中是以鍵值對(duì)為單位,鍵和值之間用=號(hào)分隔。如果大括號(hào)里有多個(gè)鍵值對(duì),用分號(hào)分隔。

  對(duì)哈希表中元素的訪問(wèn)也是通過(guò)中括號(hào),不過(guò)中括號(hào)中的是鍵名而不是下標(biāo)號(hào)。如果鍵名是合法的標(biāo)識(shí)符,那么還可以通過(guò)“.鍵名”的方式來(lái)訪問(wèn)。比如

  1. PS F:\> $a = @{abc=1; "bcd"=2; 3="James Fancy"} 
  2. PS F:\> $a["abc"] 
  3. PS F:\> $a.bcd = "Hello" 
  4. PS F:\> "$($a['bcd']) $($a[3])" # $(...) 表示運(yùn)算表達(dá)式 
  5. Hello James Fancy 
  6. PS F:\> 

  +和+=,可以聯(lián)接兩個(gè)數(shù)組并產(chǎn)生一些新的數(shù)組;它也可以將一個(gè)元素聯(lián)連到數(shù)組上。

  1. PS F:\> @("hello") + "james", "fancy" 
  2. hello 
  3. james 
  4. fancy 
  5. PS F:\> $a = "hello", "james" 
  6. PS F:\> $a += "fancy" 
  7. PS F:\> $a 
  8. hello 
  9. james 
  10. fancy 
  11. PS F:\> 

  *和*=,將數(shù)組重復(fù)指定次數(shù),并將所有這些元素作為一個(gè)新的數(shù)組返回。

  1. PS F:\> "james", "fancy" * 2 
  2. james 
  3. fancy 
  4. james 
  5. fancy 
  6. PS F:\> $a = @("j.fan") 
  7. PS F:\> $a *= 3 
  8. PS F:\> $a 
  9. j.fan 
  10. j.fan 
  11. j.fan 
  12. PS F:\> 

  -contains, -notcontains,用于判斷數(shù)組中是否有某個(gè)數(shù)據(jù),支持i和c前綴用于字符串比較。

  1. PS F:\> "abc", "bcd" -contains "BCD" 
  2. True 
  3. PS F:\> "abc", "bcd" -ccontains "BCD" 
  4. False 
  5. PS F:\> 

6. 位運(yùn)算符

  Powershell有4個(gè)位運(yùn)算符,-band(按位與)、-bor(按位或)、-bxor(按位異或)、-bnot(按位取反)。很不幸,沒(méi)有移位運(yùn)算符。

  1. PS F:\> (0x6b -band 0xf0).toString("X") 
  2. 60 
  3. PS F:\> (0x6b -bor 0x0f).toString("X") 
  4. 6F 
  5. PS F:\> (0x6b -bxor 0xff).toString("X") 
  6. 94 
  7. PS F:\> (-bnot 0x6b).toString("X") 
  8. FFFFFF94 
  9. PS F:\> 

7. 類(lèi)型運(yùn)算符

  類(lèi)型運(yùn)算符一共就3個(gè),兩個(gè)用于判斷類(lèi)型:-is、-isnot;還有一個(gè)用于轉(zhuǎn)換類(lèi)型:-as。

  1. PS F:\> 1 -is [int] 
  2. True 
  3. PS F:\> 1 -isnot [int] 
  4. False 
  5. PS F:\> "0xff" -as [int] 
  6. 255 
  7. PS F:\> [int] "0xff" # 強(qiáng)制類(lèi)型,和上句同樣效果 
  8. 255 
  9. PS F:\> 

8. 重定向運(yùn)算符

  關(guān)于重定向,這是所有控制臺(tái)中的一個(gè)重要話(huà)題,還是找個(gè)時(shí)間專(zhuān)門(mén)來(lái)記錄下吧。這次,只把幾個(gè)關(guān)于重定向的運(yùn)算符列出來(lái)。

  >,將輸出發(fā)送到指定文件。
  >>,將輸出追加到指定文件的內(nèi)容。
  2>,將錯(cuò)誤發(fā)送到指定文件。
  2>>,將錯(cuò)誤追加到指定文件的內(nèi)容。
  2>&1,將錯(cuò)誤發(fā)送到成功輸出流。

9. 其它運(yùn)算符

  &,調(diào)用運(yùn)算符。如果后面接一個(gè)命令,那它和沒(méi)帶&符號(hào),直接輸入命令沒(méi)啥區(qū)別。但是,如果有一個(gè)保存著命令名稱(chēng)的變量,&就很有用了……還有一點(diǎn)需要注意的是,這個(gè)變量只能是命令本身,不能帶參數(shù),不然會(huì)出錯(cuò)的。

  1. PS F:\> $cmd = "echo Hello James" 
  2. PS F:\> & $cmd # 哇哦,這個(gè)會(huì)出錯(cuò)哦 
  3. 無(wú)法將“echo Hello James”項(xiàng)識(shí)別為 cmdlet、函數(shù)、腳本文件或可運(yùn)行程序的名稱(chēng)。請(qǐng)檢查名稱(chēng)的拼寫(xiě),如果 
  4. 包括路徑,請(qǐng)確保路徑正確,然后重試。 
  5. 所在位置 行:1 字符: 2 
  6. + & <<<< $cmd 
  7. + CategoryInfo : ObjectNotFound: (echo Hello James:String) [], CommandNotFoundExcepti 
  8. on 
  9. + FullyQualifiedErrorId : CommandNotFoundException 
  10.  
  11. PS F:\> $cmd = "echo" 
  12. PS F:\> & $cmd Hello James # 這樣就對(duì)啦 
  13. Hello 
  14. James 
  15. PS F:\> 

  ::(雙冒號(hào)),靜態(tài)成員運(yùn)算符。這個(gè)其實(shí)以之前的示例中已經(jīng)用過(guò)了,就是調(diào)用靜態(tài)成員的。比如之前用到的[string]::format,[math]::floor等。再比如

  1. PS F:\> [system.text.encoding]::utf8.toString() 
  2. System.Text.UTF8Encoding 
  3. PS F:\> [guid]::newGuid() 
  4.  
  5. Guid 
  6. ---- 
  7. 76e2b9ed-71f7-4b91-89c6-1c329df82e96 
  8.  
  9.  
  10. PS F:\> 

  .(點(diǎn)號(hào)),訪問(wèn)對(duì)象的成員的運(yùn)算符。這個(gè)也用過(guò)很多次了,再舉個(gè)例子:

  1. PS F:\> $r = new-object random 
  2. PS F:\> $r.next() # 獲取一個(gè)隨機(jī)整數(shù) 
  3. 397489906 
  4. PS F:\> $r.getType().fullName 
  5. System.Random 
  6. PS F:\> 

  .(點(diǎn)號(hào)),還有一個(gè)作用,用于獲取來(lái)源——就是有點(diǎn)像C/C++中的#include。這個(gè)時(shí)候它的后面接一個(gè)腳本文件,比如

  1. PS F:\> echo "`$a = `"Hello J.Fan`"" > hello.ps1 
  2. PS F:\> cat .\hello.ps1 # 顯示hello.ps1的內(nèi)容 
  3. $a = "Hello J.Fan" 
  4. PS F:\> .\hello.ps1 # 不用.號(hào)調(diào)用腳本。注意:這里的點(diǎn)號(hào)是代表當(dāng)前目錄 
  5. PS F:\> $a 
  6. PS F:\> . .\hello.ps1 # 用.號(hào)引入腳本 
  7. PS F:\> $a 
  8. Hello J.Fan 
  9. PS F:\> 

  總算把運(yùn)算符搞定了,真沒(méi)想到居然這么多!

以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)