字符串修剪和拆分

时间:2017-08-28 21:12:41

标签: powershell parsing split trim

我有一个我读过的文本文件,我需要从中获取值。

示例文本文件:

[Site 01]
DBServer=LocalHost
DBName=Database01
Username=admin
Password=qwerty

[Site 02]
DBServer=192.168.0.10
DBName=Database02
Username=admin
Password=qwerty

目前,我的代码会读取整个文件,并将每个代码作为每个行DBServer=的数组条目放置,并且此文本文件可以包含多个网站:

$NumOfSites = Get-Content $Sites |
              Select-String -Pattern "DBServer=" -Context 0,3
$i = 0
$NumOfSites | ForEach-Object {
    $svr  = $NumOfSites[$i] -isplit "\n" |
            % { ($_ -isplit 'DBServer=').Trim()[1] }
    $db   = $NumOfSites[$i] -isplit "\n" |
            % { ($_ -isplit 'DBName='.Trim())[1] }
    $uid  = $NumOfSites[$i] -isplit "\n" |
            % { ($_ -isplit 'Username='.Trim())[1] }
    $pswd = $NumOfSites[$i] -isplit "\n" |
            % { ($_ -isplit 'Password='.Trim())[1] }
    $i = $i+1
}

如果没有一些额外的空格或一些很好的字符串变量,我无法正确地拆分每个属性。 我只需要提取信息以作为我文件示例格式的变量放入SQL连接行。

2 个答案:

答案 0 :(得分:3)

除了记录标题(即[Site 01])之外,其余的ConvertFrom-StringData可以正常处理。我们可以将记录转换为直接在标题行上拆分的对象或多或少。 ConvertFrom-StringData将多行字符串转换为哈希表,您可以将其转换为[PSCustomObject]和中提琴,您可以使用易于使用的对象。

$NumOfSites = Get-Content $Sites -raw
$SiteObjects = $NumOfSites -split '\[.+?\]'|%{[PSCustomObject](ConvertFrom-StringData -StringData $_)}

然后你可以根据自己的需要操纵$SiteObjects(如果需要,可以输出到CSV,或使用Select-Object过滤任何属性)。或者,如果您正在寻求建立连接,您可以根据需要循环建立连接...

ForEach($Connection in $SiteObjects){
    $ConStr = "Server = {0}; Database = {1}; Integrated Security = False; User ID = {2}; Password = {3};" -f $Connection.DBServer.Trim(), $Connection.DBName.Trim(), $Connection.Username.Trim(), $Connection.Password.Trim()
    <Do stuff with SQL>
}

修改:自示例文本更改为添加<pre></pre>后更新我的答案。我们只需要删除它们,并且由于OP在null值上的方法出错,我们也会过滤null。

$NumOfSites = Get-Content $Sites -raw
$SiteObjects = $NumOfSites -replace '<.*?>' -split '\[.+?\]' | ?{$_} |%{[PSCustomObject](ConvertFrom-StringData -StringData $_)}
ForEach($Connection in $SiteObjects){ 
    $svr = $Connection.DBServer.Trim() 
    $db  = $Connection.DBName.Trim() 
    $uid = $Connection.Username.Trim() 
    $pwd = $Connection.Password.Trim()
}

答案 1 :(得分:1)

如果你只关心在等于之后获得价值,这里有一个建议:

Get-Content Example.txt |
  ForEach-Object {
      Switch -Regex ($_) {
          'dbs.+=' { $svr = ($_ -replace '.+=').Trim()
          .. etc ..
      }
  }
管道传递给Get-Content

ForEach-Object会将每一行解释为自己的对象。

编辑:
你大部分都在那里,但-split

是不必要的
$NumOfSites = Get-Content $Sites | Select-String -pattern "DBServer=" -Context 0,3
$NumOfSites | ForEach-Object {
    Switch -Wildcard ($_) {
        'DBS*=' { $svr = ($_ -replace '.+=').Trim() }
        'DBN*=' { $db  = ($_ -replace '.+=').Trim() }
        'U*='   { $uid = ($_ -replace '.+=').Trim() }
        'P*='   { $pw  = ($_ -replace '.+=').Trim() }
    }
}