美文网首页文本处理(grep, sed和awk等)
Windows PowerShell 学习笔记其三(字符串与数组

Windows PowerShell 学习笔记其三(字符串与数组

作者: rollingstarky | 来源:发表于2019-03-10 01:39 被阅读21次

    字符串介绍

    两种类型

    PowerShell 下的字符串主要有两种类型:非扩展(nonexpanding)和扩展(expanding)型。
    这里的“扩展”和“非扩展”指的是对字符串中包含的变量转义符是否进行解析。
    扩展型字符串需要用双引号括起来,而非扩展型字符串使用单引号

    实际效果如下:

    PS > $username = "starky"
    PS > echo "hi, my name is $username. `nAnother line"
    hi, my name is starky.
    Another line
    PS > echo 'hi, my name is $username. `nwithin the same line'
    hi, my name is $username. `nwithin the same line
    

    在上面的例子中,双引号包裹的字符串对变量 $username 和转义符 `n(等同于 bash 里的 \n)进行了解析,自动替换为变量和转义符代表的内容。
    而单引号包裹的字符串则只是将美元符、反引号等符号视为普通的字符,不做任何处理直接打印输出。

    PS:PowerShell 里的转义符是反引号 ` 而不是 bash 里的反斜杠

    多行格式化文本

    PowerShell 支持创建 here string,即多行格式化文本,类似 Python 里的三引号。只需要将多行文本包裹在成对的 @""@ 符号中即可。示例如下:

    PS > $mystring = @"
    >> This is the first line
    >> of a very long string. A "here string"
    >> lets you create blocks of text
    >> that span several lines.
    >> "@
    >>
    PS > $mystring
    This is the first line
    of a very long string. A "here string"
    lets you create blocks of text
    that span several lines.
    
    字符串中的动态内容

    前面有提到过,由双引号包裹的字符串为“扩展”型字符串,可以对其中包含的变量等自动进行替换。
    其实也可以在字符串中,以 $(expression) 的格式插入表达式或一系列 PowerShell 命令,示例如下:

    PS > "1 + 2 equals $(1 + 2)"
    1 + 2 equals 3
    

    还可以使用 PowerShell 的字符串格式化操作符在字符串中插入动态内容,它遵循和 .NET 一样的字符串格式化规则。示例如下:

    PS > $header = "Report for Today"
    PS > $mystring = "{0}`n{1}" -f $header,('-' * $header.Length)
    PS > $mystring
    Report for Today
    ----------------
    

    示例 2:

    PS > $number1 = 10
    PS > $number2 = 32
    PS > "$number2 divided by $number1 is $($number2 / $number1)"
    32 divided by 10 is 3.2
    PS > "{0} divided by {1} is {2}" -f $number2, $number1, ($number2 / $number1)
    32 divided by 10 is 3.2
    

    字符串操作

    检索与替换

    PowerShell 提供了多种用于字符串搜索和匹配的方法。

    • -like
      -like 操作符用于判断字符串是否匹配特定的模式,该模式中可以包含通配符
    PS > "Hello World" -like "*llo W*"
    True
    
    • -match
      -match 操作符用于判断字符串是否匹配特定的正则表达式
    PS > "Hello World" -match '.*l[l-z]o W.*$'
    True
    
    • Contains()
      Contains() 方法用于判断一个字符串是否包含了另一个较短的字符串:
    PS > "Hello World".Contains("World")
    True
    
    • IndexOf()
      IndexOf() 方法可以用来获取一个字符串在另一个字符串中的位置索引:
    PS > "Hello World".IndexOf("World")
    6
    
    • Replace()
      Replace() 方法用于将字符串中的一部分替换为另一个字符串:
    PS > "Hello World".Replace("World", "PowerShell")
    Hello PowerShell
    

    另外,使用 PowerShell 的 -replace 操作符搭配上正则表达式,可以完成更加高级的替换任务:

    PS > "Hello World" -replace '(.*) (.*)', '$2 $1'
    World Hello
    
    分割、合并、修剪
    • -split
      -split 操作符可以用来将指定字符串分割成一系列的字符片段:
    PS > "a-b-c-d-e-f" -split "-c-"
    a-b
    d-e-f
    PS > "a-b-c-d-e-f" -split "b|[d-e]"
    a-
    -c-
    -
    -f
    
    • -join
      -join 操作符用于将多个字符片段合并为一个完整的字符串
    PS > $list = "Hello","World"
    PS > $list
    Hello
    World
    PS > $list -join ", "
    Hello, World
    
    • Trim()
      Trim() 方法用于去除字符串两边的空白字符:
    PS > $text = " `t  Test String`t  `t"
    PS > "|" + $text.Trim() + "|"
    |Test String|
    

    列表、数组与哈希表

    创建数组和列表

    创建和初始化一个数组在 PowerShell 里非常简单,用很常见的赋值语句即可:

    PS > $myArray = 1,2,"HelloWorld"
    PS > $myArray
    1
    2
    HelloWorld
    

    用上述方法创建的数组是没有数据类型限制的,即该数组在初始化时可以包含任何类型的数据。

    创建指定长度的数组,可以使用 New-Object 命令:

    PS > $myArray = New-Object "int32[]" 4
    PS > $myArray[3] = 3
    PS > $myArray
    0
    0
    0
    3
    PS > $myArray[4] = 4
    索引超出了数组界限。
    所在位置 行:1 字符: 1
    + $myArray[4] = 4
    + ~~~~~~~~~~~~~~~
        + CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
        + FullyQualifiedErrorId : System.IndexOutOfRangeException
    

    创建指定类型的数组,可以使用 .NET 框架提供的强类型的集合:

    PS > $list = New-Object Collections.Generic.list[Int]
    PS > $list.add(10)
    PS > $list.add("Hello")
    无法将“Add”的参数“item”(其值为“Hello”)转换为类型“System.Int32”:“无法将值“Hello”转换为类型“System.Int32”。
    错误:“输入字符串的格式不正确。””
    所在位置 行:1 字符: 1
    + $list.add("Hello")
    + ~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodException
        + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
    
    多维数组

    PowerShell 可以使用 @() 形式的语法创建多维数组

    PS > $jagged = @(
    >> (1,2,3,4),
    >> (5,6,7,8)
    >> )
    PS > $jagged[0][0]
    1
    PS > $jagged[1][3]
    8
    

    也可以使用下面的方式:

    PS > $multidimensional = New-Object "int32[,]" 2,4
    PS > $multidimensional[0,0] = 1
    PS > $multidimensional[1,3] = 8
    PS > $multidimensional
    1
    0
    0
    0
    0
    0
    0
    8
    
    操作数组中的元素

    可以通过位置索引(从 0 开始)获取数组中的某个元素:

    PS > $myArray = 1,2,"Hello World"
    PS > $myArray[0]
    1
    PS > $myArray[2]
    Hello World
    

    当然也可以对数组进行分片操作,即获取数组中的某“一段”元素:

    PS > $myArray
    1
    2
    Hello World
    PS > $myArray[1..2]
    2
    Hello World
    

    在对数组进行分片时,PowerShell 提供了如下的一个小技巧,可以对输出后的元素进行灵活的排序:

    PS > $myArray = 0,1,2,3,4,5
    PS > $myArray[3..5 + 2 + 0..1]
    3
    4
    5
    2
    0
    1
    
    Foreach-Object

    如果需要挨个访问数组中的每一个元素,可以使用 Foreach-Object 命令:

    PS > $myArray = 1,2,3
    PS > $sum = 0
    PS > $myArray | Foreach-Object { $sum += $_ }
    PS > $sum
    6
    

    当然也可以稍微复杂点,通过位置索引和 for 循环访问数组的每一个元素:

    PS > $myArray = 1,2,3
    PS > $sum = 0
    PS > for($i = 0; $i -lt $myArray.Count; $i++) {
    >> $sum += $myArray[$i]
    >> }
    PS > $sum
    6
    
    排序

    使用 Sort-Object 命令可以对数组元素进行排序后再输出:

    PS > dir
    
    
        目录: D:\Program\python
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    d-----        2019/2/28     22:43                pyqt
    d-----         2019/3/3      0:17                speech
    -a----         2019/3/6     22:13          26434 test.html
    -a----         2019/3/6     22:00            174 test.md
    
    PS > Get-ChildItem | Sort-Object -Descending Length | select Name,Length
    
    Name      Length
    ----      ------
    test.html  26434
    test.md      174
    pyqt
    speech
    

    使用 Get-ChildItem 获取当前目录下所有文件的列表,再把该列表传递给 Sort-Object ,根据文件占用空间的大小(Length)逆序输出 Name 和 Length 项。

    在使用 Sort-Object 对元素进行排序时,可以自由选择排序依据的条件。如根据首字母对字符串进行排序:

    PS > "Hello","World","And","Shell" | Sort-Object
    And
    Hello
    Shell
    World
    

    根据次字母对字符串进行排序:

    PS > "Hello","World","And","Shell" | Sort-Object { $_.Substring(1,1) }
    Hello
    Shell
    And
    World
    
    数组与运算符
    确定数组与元素的包含关系

    确定数组与元素的包含关系,可以使用 -contains 或者 -in 操作符:

    PS > "Hello","World" -contains "Hello"
    True
    PS > "Hello","World" -contains "Shell"
    False
    PS > "Hello" -in "Hello","World"
    True
    PS > "Shell" -in "Hello","World"
    False
    
    合并数组

    可以使用算术运算符 + 对数组进行合并操作:

    PS > $firstArray = "Element 1","Element 2","Element 3"
    PS > $secondArray = 1,2,3
    PS > $firstArray + $secondArray
    Element 1
    Element 2
    Element 3
    1
    2
    3
    PS > $array = 1,2
    PS > $array += 3,4
    PS > $array
    1
    2
    3
    4
    
    匹配数组中的元素

    可以使用 -eq-match-like 操作符对数组中的元素进行匹配:

    PS > $array = "Item 1","Item 2","Item 3","Item 1","Item 12"
    PS > $array -eq "Item 1"
    Item 1
    Item 1
    PS > $array -like "*1*"
    Item 1
    Item 1
    Item 12
    PS > $array -match "Item .."
    Item 12
    

    其中 -eq 表示完全匹配,-like 支持使用通配符-match 支持正则表达式。

    更复杂的匹配条件可以使用 Where-Object

    PS > $array = "Item 1","Item 2","Item 3","Item 1","Item 12"
    PS > $array | Where-Object { $_.Length -gt 6 }
    Item 12
    
    移除数组中的元素

    为了移除数组中符合特殊规则的元素,可以使用 -ne-notlike-notmatch 等比较操作符:

    PS >$array = "Item 1","Item 2","Item 3","Item 1","Item 12"
    PS >$array -ne "Item 1"
    Item 2
    Item 3
    Item 12
    PS > $array -notlike "*1*"
    Item 2
    Item 3
    PS > $array -notmatch "Item .."
    Item 1
    Item 2
    Item 3
    Item 1
    
    获取大于或小于特定值的元素

    -gt-ge-lt-le 等比较操作符可以用来获取数组中大于或小于某个特定值的元素。

    PS:其中 -gt 表示大于(great than),-ge 表示大于等于(great and equal),-lt 表示小于(less than),-le 表示小于等于(less and equal)。

    PS > $array = "Item 1","Item 2","Item 3","Item 1","Item 12"
    PS > $array -ge "Item 3"
    Item 3
    PS > $array -lt "Item 2"
    Item 1
    Item 1
    Item 12
    
    ArrayList

    通过类似 $array = 1,2,3,4 这种赋值的方式创建的数组,其长度固定的。
    可以通过位置索引访问其中的某个值,并对它重新赋值。但是不能直接添加或者删除数组中的元素:

    PS > $array = 0,1,2,3
    PS > $array[1]
    1
    PS > $array[0]=1
    PS > $array
    1
    1
    2
    3
    PS > $array.Add(4)
    使用“1”个参数调用“Add”时发生异常:“集合的大小是固定的。”
    所在位置 行:1 字符: 1
    + $array.add(4)
    + ~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : NotSupportedException
    

    如果需要在数组中添加或者删除元素,可以使用 +-ne-match-gt 等比较操作符,获取数组中匹配某个条件的元素,并将它们赋值给新的变量,原数组中元素的值则不受影响:

    PS > $original = 1,2,3,4
    PS > $new1 = $original + 5
    PS > $new1
    1
    2
    3
    4
    5
    PS > $new2 = $original -ne 4
    PS > $new2
    1
    2
    3
    PS > $new3 = $original -gt 2
    PS > $new3
    3
    4
    PS > $original
    1
    2
    3
    4
    

    在面对长度很大的数组时,上述的添加、移除、搜索等操作就会稍微显得效率较低。所以 PowerShell 提供了 ArrayList 数据类型,可以直接对数组本身进行添加、删除等操作:

    PS > $collection = New-Object System.Collections.ArrayList
    PS > [void] $collection.Add("Hello")
    PS > [void] $collection.AddRange(("World","How","Are","You"))
    PS > $collection
    Hello
    World
    How
    Are
    You
    PS > $collection.RemoveAt(1)
    PS > $collection
    Hello
    How
    Are
    You
    

    [void] 可以省略操作执行后返回的状态值。

    哈希表

    可以使用 @{} 形式的语法创建哈希表(或关联数组)。

    PS > $myHashtable = @{ Key1 = "Value1"; "Key 2" = 1,2,3 }
    PS > $myHashtable["New Item"] = 5
    PS > $myHashtable
    
    Name                           Value
    ----                           -----
    Key 2                          {1, 2, 3}
    Key1                           Value1
    New Item                       5
    
    按哈希表的键或值排序
    PS > $myHashtable = @{}
    PS > $myHashtable["Hello"] = 3
    PS > $myHashtable["Ali"] = 2
    PS > $myHashtable["Alien"] = 4
    PS > $myHashtable["Duck"] = 1
    PS > $myHashtable
    
    Name                           Value
    ----                           -----
    Hello                          3
    Duck                           1
    Alien                          4
    Ali                            2
    
    
    PS > $myHashtable.GetEnumerator() | Sort Name
    
    Name                           Value
    ----                           -----
    Ali                            2
    Alien                          4
    Duck                           1
    Hello                          3
    
    PS > $myHashtable.GetEnumerator() | Sort Value
    
    Name                           Value
    ----                           -----
    Duck                           1
    Ali                            2
    Hello                          3
    Alien                          4
    

    参考书籍

    Windows PowerShell Cookbook, 3rd Edition

    相关文章

      网友评论

        本文标题:Windows PowerShell 学习笔记其三(字符串与数组

        本文链接:https://www.haomeiwen.com/subject/zxkiuqtx.html