【问题标题】:powershell: split the output and print after the select-stringpowershell:在选择字符串之后拆分输出和打印
【发布时间】:2018-06-06 00:43:01
【问题描述】:

首先,这是我第一次使用 powershell。一切都很新。我的脚本看起来像这样。

$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = "username@domain.com"
$Password = "password"

$to = "Username @domain.com"

$subject = "daily_check"
$body = (Get-Content 'C:\Users\xyz\Downloads\mylog.log' | Select-String 'string.string1.string2 - Request:') | Out-String

$message = New-Object System.Net.Mail.MailMessage
$message.subject = $subject
$message.body = $body
$message.to.add($to)
#$message.cc.add($cc)
$message.from = $username
#$message.attachments.add($attachment)

$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.send($message)

我收到一封成功的电子邮件,其中包含所有带有搜索字符串的行,它看起来如下所示。

INFO    2018-06-01 06:03:01,855 string.string1.string2 - Request: QWERTY- 123 Request: abc- XX1343XX123-01 Request: Type- BB
INFO    2018-06-01 11:06:54,551 string.string1.string2 - Request: QWERTY- 123 Request: abc- XX-12573XX123-00 Request:  Type- BB
INFO    2018-06-01 11:51:50,124 string.string1.string2 - Request: QWERTY- 123 Request: abc- 123XX122233-03 Request:  Type- BB
INFO    2018-06-01 12:20:15,076 string.string1.string2 - Request: QWERTY- 123 Request: abc- XX-12563XX123-00 Request:  Type- BB
INFO    2018-06-01 12:24:25,233 string.string1.string2 - Request: QWERTY- 123 Request: abc- XX-123XX12913-00 Request:  Type- BB

但我希望我的输出如下所示。

2018-06-01 06:03:01, QWERTY- 123 abc- XX1343XX123-01 Type- BB
2018-06-01 11:06:54, QWERTY- 123 abc- XX-12573XX123-00 Type- BB
2018-06-01 11:51:50, QWERTY- 123 abc- 123XX122233-03 Type- BB
2018-06-01 12:20:15, QWERTY- 123 abc- XX-12563XX123-00 Type- BB
2018-06-01 12:24:25, QWERTY- 123 abc- XX-123XX12913-00 Type- BB

我正在使用-split ' ' 并尝试将每个字符串转换为变量并使用它们,但我做不到。即使我这样做了,也应该有更好的方法来做到这一点。任何帮助表示赞赏。谢谢。

【问题讨论】:

    标签: powershell windows-10


    【解决方案1】:

    Bruce Payette's helpful answer 向您展示了如何使用-replace 运算符,通过带有令牌提取 的正则表达式组合 匹配 方面。

    提供一种替代方案,让Select-String 进行匹配,然后通过-split 处理结果行:

    Get-Content 'C:\Users\xyz\Downloads\mylog.log' |
      Select-String 'string\.string1\.string2 - Request:' |
        ForEach-Object { (-split $_)[1,2,6,7,9,10,12,13] -join ' ' }
    
    • -split 将每个匹配行(通过ForEach-Object 提供为$_)按空格拆分为一个标记数组。

    • [1,2,6,7,9,10,12,13] 然后将索引为12、...的标记提取为数组...

    • ...其元素-join ' ' 连接形成一个以空格分隔的列表。

    • 顺便说一句:注意. 字符的方式。在传递给Select-String 的模式中被转义为\.,以确保它们被视为literal . 字符,而不是正则表达式元字符 .,匹配任何字符。

    使用您的示例输入,上述结果:

    2018-06-01 06:03:01,855 QWERTY- 123 abc- XX1343XX123-01 Type- BB
    2018-06-01 11:06:54,551 QWERTY- 123 abc- XX-12573XX123-00 Type- BB
    2018-06-01 11:51:50,124 QWERTY- 123 abc- 123XX122233-03 Type- BB
    2018-06-01 12:20:15,076 QWERTY- 123 abc- XX-12563XX123-00 Type- BB
    2018-06-01 12:24:25,233 QWERTY- 123 abc- XX-123XX12913-00 Type- BB
    

    注意:与您的问题不同,输出包括第二个标记中, 后面的数字;例如,06:03:01,855 而不仅仅是 06:03:01,。 如果您真的想在, 之后删除该部分,则需要做更多工作。


    由于未知原因,使用运算符 -split-join 不适用于 OP,因此这里有一个变体解决方案,它直接使用近乎等效的 .NET 方法:

    Get-Content 'C:\Users\xyz\Downloads\mylog.log' |
      Select-String 'string\.string1\.string2 - Request:' |
        ForEach-Object { [string]::Join(' ', ([regex]::split($_, '\s+')[1,2,6,7,9,10,12,13])) }
    

    【讨论】:

    【解决方案2】:

    看看-replace 运算符和regular expressions。要将源格式转换为所需格式,您可以执行以下操作:

    $p = "^INFO +([0-9:, -]+)string.string1.string2 - Request: ([a-z-]+) ([0-9]+) Request: ([a-z-]+) ([A-Za-z0-9-]+) Request: (.*$)"
    $newstring = $oldstring -replace $p, '$1 $2 $3 $4 $5 $6'
    

    此代码使用一个简单(但相当长)的正则表达式从源字符串中提取子匹配项,然后使用反向引用将整个字符串替换为新字符串,以将子匹配项替换到字符串中。

    【讨论】:

    • 我无法在我的脚本中使用任何运算符,例如替换、拆分和加入。看了很多互联网的东西,仍然摸不着头脑。知道为什么吗?
    猜你喜欢
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    相关资源
    最近更新 更多