[TOC]
0x00 PS字符串内容分隔识别校验
替换 - Replace
描述: PowerShell 文本替换方式演示巧妙用法参考。
- .Replace(“原字符串”,”新字符串”)
- -Replace “原字符串(支持正则)”,”新字符串”
- -Creplace “原字符串(支持正则且大小写敏感)”,”新字符串”
基础示例:
代码语言:javascript复制# - 1.字符串"Hello WeiyiGeek"将这个字符串的Hello替换为Hi。(注意默认不是大小写敏感的)
"Hello WeiyiGeek".Replace("Hello","Hi") # 结果: Hi WeiyiGeek
"Hello WeiyiGeek".Replace("hello","Hi") # 结果: Hi WeiyiGeek
# - 2.将字符串中特殊字符利用正则表达式进行替换。(注意采用得形式)
"He,.l^lo Weiy'./iGeek" -Replace 'W','' # 结果: HelloWeiyiGeek
"Hi WeiyiGeek" -Replace '(.*) (.*)','$2 $1' # 结果: WeiyiGeek Hi (利用元组进行替换)
# - 3.采用-Replace形式时不进行正则表达式解析匹配
"[Hello] WeiyiGeek" -Replace '[Hello]','Hi' # 结果: Hi WeiyiGeek
"[Hello] WeiyiGeek" -Replace ([Regex]::Escape("[Hello]")),"Hi" # 结果: Hi WeiyiGeek
# - 4.该操作符默认是大小写敏感的,即只能完全大小匹配使进行替换
"[Hello] WeiyiGeek" -creplace 'hello','Hi' # 结果: [Hello] WeiyiGeek
"[Hello] WeiyiGeek" -creplace 'Hello','Hi' # 结果: [Hi] WeiyiGeek
"[Hello] WeiyiGeek" -creplace ([Regex]::Escape("[hello]")),"Hi"
实践案例
代码语言:javascript复制# -1.我想从字符串中搜索具有特定格式的数字并使用powershell将最后一个数字增加1,该字符串取自大型txt文件。
$str = "Android version 4.4.2, Alfa = 1.2.0400, Beta = 2.0.0200, Prod 3.4.0104" # 我想将beta版本增加1(2.0.0200==> 2.0.0201)运行powershell命令后:$str = "Android version 4.4.2, Alfa = 1.2.0400, Beta = 2.0.0201, Prod 3.4.0104"
# 方式1
if($str -match "(?<=Beta = d .d .)(?<bv>d )"){
$str -replace "(?<=Beta = d .d .)(d )", ("{0:0000}" -f (([int]::Parse($matches.bv) 1)))
}
# 方式2: 注意此处没有 运算符是因为其运算符仅适用于数字,而非字符串.
[regex]::Replace($str, '(?<Head>. .)(?<Beta>d )(?<Tail>,[^,] )$',
{ param( [System.Text.RegularExpressions.Match]$m )
$bv = 1 $m.Groups['Beta'].Value
'{0}{1:0000}{2}' -f $m.Groups['Head'].Value,$bv,$m.Groups['Tail'].Value
}
)
Tips : 非常注意Replace中得[Regex]
类里面有个Escape静态方法非常方便我们进行禁用正则解析。
匹配 - Match
描述: PowerShell 文本匹配方式演示巧妙用法参考。
- match 运算符: 通过 $Matches来获取字段。
- matches 方法: 通过该方法获取字段。
基础示例:
代码语言:javascript复制# - 1.基础字符串匹配显示match
PS > "[Hello] WeiyiGeek" -match '(?<name>(Ww. k$))' # True
PS > $Matches.name # WeiyiGeek
# - 2.采用matches方法进行多次匹配邮箱格式
$txt='WeiyiGeek Email <master@weiyigeek.top>;
test <test@weiyigeek.top>;
demo <demo@weiyigeek.top>;'
[regex]::matches($txt, '<(. )>;') | %{$_.Groups[1].Value}
# master@weiyigeek.top
# test@weiyigeek.top
# demo@weiyigeek.top
# - 3.网页指定正则表达式匹配到得字符串获取
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$ true }
$WebClient=New-Object System.Net.WebClient
$url="https://www.weiyigeek.top"
$WebClient.DownloadString($url) -match '(?<name>(Ww. k))'|out-null # 网站字符串
$Matches.name # WeiyiGeek
$WebClient.DownloadString("http://ident.me/") -match '(?<ip>(d .){3}d )'|out-null # 外网地址
$Matches.ip # 120.17.50.229
0x03 内存字符串处理
Select-String 命令 - 在字符串和文件中查找文本
描述:可以按照字符串以及属性进行过滤显示通过管道符;
基础语法:
代码语言:javascript复制# 语法
Select-String [-Pattern] <System.String[]> [-AllMatches] [-CaseSensitive] [-Context <System.Int32[]>] [-Encoding {ASCII | BigEndianUnicode | Default | OEM | Unicode | UTF7 | UTF8 | UTF32}] [-Exclude <System.String[]>] [-Include <System.String[]>] -InputObject <System.Management.Automation.PSObject> [-List] [-NotMatch] [-Quiet] [-SimpleMatch] [<CommonParameters>]
基础示例:
代码语言:javascript复制# 1.过滤选择显示特定的字符串
PS > ipconfig | Select-String "IPv6"
# 本地链接 IPv6 地址. . . . . . . . : fe80::d97d:fe6c:10bf:4244
# 本地链接 IPv6 地址. . . . . . . . : fe80::34d5:4b52:1627:64dc
# 本地链接 IPv6 地址. . . . . . . . : fe80::50fc:1560:33a5:b73f%5
ipconfig | Select-String "以太网"
# 以太网适配器 以太网:
# 以太网适配器 VMware Network Adapter VMnet1:
# 以太网适配器 VMware Network Adapter VMnet8:
# 2.查找区分大小写的匹配项(默认不区分大小写)
# SimpleMatch是一个可选参数,指定模式中的字符串不被解释为正则表达式。
'Hello', 'HELLO' | Select-String -Pattern 'HELLO' -CaseSensitive -SimpleMatch
HELLO
# 3.在文本文件中查找匹配项(简单通配符|正则匹配)
Get-Alias | Out-File -FilePath .Alias.txt
Get-Command | Out-File -FilePath .Command.txt
# Simple Match
Select-String -Path .*.txt -Pattern 'Get-' -SimpleMatch
# Alias.txt:8:Alias cat -> Get-Content
# Alias.txt:28:Alias dir -> Get-ChildItem
# Alias.txt:43:Alias gal -> Get-Alias
# Command.txt:966:Cmdlet Get-Acl
# Command.txt:967:Cmdlet Get-Alias
# Find a pattern match
Select-String .Testfile1.txt -Pattern "Weiy|3"
# Testfile1.txt:1:Weiyieek
# Testfile1.txt:4:3
Select-String -Path "$PSHOMEen-US*.txt" -Pattern '?'
# C:Program FilesPowerShell6en-USdefault.help.txt:27: beginning at https://go.microsoft.com/fwlink/?LinkID=108518.
# C:Program FilesPowerShell6en-USdefault.help.txt:50: or go to: https://go.microsoft.com/fwlink/?LinkID=210614
# 4.在函数中使用Select字符串
PS> Function Search-Help
>> {
>> $PSHelp = "$PSHOMEen-US*.txt"
>> Select-String -Path $PSHelp -Pattern 'About_'
>> }
PS> Search-Help
C:WindowsSystem32WindowsPowerShellv1.0en-USabout_ActivityCommonParameters.help.txt:2: about_ActivityCommonParameters
C:WindowsSystem32WindowsPowerShellv1.0en-USabout_ActivityCommonParameters.help.txt:31: see about_WorkflowCommonParameters.
C:WindowsSystem32WindowsPowerShellv1.0en-USabout_ActivityCommonParameters.help.txt:33: about_CommonParameters.
# 5.在Windows事件日志中搜索字符串
$Events = (Get-WinEvent -LogName Application -MaxEvents 50)
$Events | Select-String -InputObject {$_.message} -Pattern '错误'
# “C:Program Files (x86)GoogleUpdateGoogleUpdate.exe”的激活上下文生成失败。在指令清单或策略文件“C:Program Files (x86)GoogleUpdateGoogleUpdate.exe”的第 0 行出现错误。 无效的 Xml 语法。
# 6.在子目录中查找字符串 (常用)
Get-ChildItem -Path C:WindowsSystem32*.txt -Recurse | Select-String -Pattern 'Microsoft' -CaseSensitive
# 7.查找与模式不匹配的字符串
Get-Command | Out-File -FilePath .Command.txt
Select-String -Path .Command.txt -Pattern 'Get', 'Set' -NotMatch
# 8.查找匹配前后的行
Get-Command | Out-File -FilePath .Command.txt
# Context参数使用两个值before和after并用尖括号(`>`)标记输出中的模式匹配。Context参数输出第一个模式匹配之前的两行和之后的三行最后的模式匹配。
Select-String -Path .Command.txt -Pattern 'Get-Computer' -Context 2, 3
# 9.查找所有模式匹配
PS> $A = Get-ChildItem -Path "$PSHOMEen-US*.txt" | Select-String -Pattern 'PowerShell'
PS> $A
# C:WindowsSystem32WindowsPowerShellv1.0en-USabout_ActivityCommonParameters.help.txt:5: Describes the parameters that Windows PowerShell
# C:WindowsSystem32WindowsPowerShellv1.0en-USabout_ActivityCommonParameters.help.txt:9: Windows PowerShell Workflow adds the activity common
PS> $A.Matches
# Groups : {0}
# Success : True
# Name : 0
# Captures : {0}
# Index : 4
# Length : 10
# Value : PowerShell
PS> $A.Matches.Length
# 2073
PS> $B = Get-ChildItem -Path "$PSHOMEen-US*.txt" | Select-String -Pattern 'PowerShell' -AllMatches
PS> $B.Matches.Length
# 2200
# 长度属性增加,因为对于每一行,模式PowerShell的每一次出现都会被计数。
# 10.从文本文件中获取前几行或者后几行
echo "ServerId = VMlinux-b71655e1
DatabaseId = db-ecb2e784
Status = completed
LocationId = 344067960796
DatabaseSize = 30
ServerId = VMlinux-0db8d45b
DatabaseId = db-cea2f7a6
Status = completed
LocationId = 344067960796
DatabaseSize = 35
ServerId = VMlinux-c5388693
DatabaseId = db-9a421bf2
Status = completed
LocationId = 344067960796
DatabaseSize = 8
etc" > result.txt
# 此处获取匹配得字符串上方得前三行
(gc result.txt | Select-String 'DatabaseSize = 35' -Context 3).context.precontext
# DatabaseId = db-cea2f7a6
# Status = completed
# LocationId = 344067960796
# 此处获取匹配得字符串下方得后三行
(gc result.txt | Select-String 'DatabaseSize = 35' -Context 3).context.precontext
#
# ServerId = VMlinux-c5388693
# DatabaseId = db-9a421bf2
PowerShell 文本处理实例(三) 4
原始文本:”data1″:111,”data2″:22,”data3″:3,”data4″:4444444,”data5″:589
要求:转换成对象
代码语言:javascript复制$rawTxt='"data1":111,"data2":22,"data3":3,"data4":4444444'
$rawTxt -split ',' | ForEach-Object {
$temp= $_ -split ':'
"{0}={1}" -f $temp[0].Substring(1,$temp[0].Length-2),$temp[1]
} | ConvertFrom-StringData
结果:
代码语言:javascript复制Name Value
---- -----
data1 111
data2 22
data3 3
data4 4444444
XML节点选择:
代码语言:javascript复制#$xml = [xml](Get-Content "c:folderapp.config")
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="IIS_VERSION" value="8" />
<add key="somekey" value="somevalue" />
</appSettings>
</configuration>
"@
$IISVersion = $xml.SelectSingleNode("//add[@key='IIS_VERSION']")
if ($IISVersion.Value -eq 7)
{
Write-Host "IIS's version is already 7"
}
else
{
Write-Host "Update IIS version to 7"
$IISVersion.Value = "7"
}
$xml.Save("c:folderapp.config")