使用PowerShell从.txt文件中的字符串中提取某些值

时间:2016-11-29 11:38:14

标签: regex powershell extract

我尝试使用PowerShell从.txt文件中的多行中提取某些值。我目前使用多个替换和删除cmd,但它没有按预期工作,有点太复杂。 有更简单的方法吗?

我的剧本:

$file = Get-Content "C:\RS232_COM2*"

foreach($line in $file){
$result1 = $file.replace(" <<<  [NAK]#99","")
$result2 = $result1.remove(0,3) #this only works for the first line for some reason...
$result3 = $result2.replace("\(([^\)]+)\)", "") #this should remove the string within paranthesis but doesn't work

.txt文件:

29 09:10:16.874 (0133563471) <<<  [NAK]#99[CAR]0998006798[CAR]
29 09:10:57.048 (0133603644) <<<  [NAK]#99[CAR]0998019022[CAR]
29 09:59:56.276 (0136542798) <<<  [NAK]#99[CAR]0998016987[CAR]
29 10:05:36.728 (0136883233) <<<  [NAK]#99[CAR]0998050310[CAR]
29 10:55:36.792 (0139883179) <<<  [NAK]#99[CAR]099805241D[CAR]0998028452[CAR]
29 11:32:16.737 (0142083132) <<<  [NAK]#99[CAR]0998050289[CAR]0998031483[CAR]
29 11:34:16.170 (0142202566) <<<  [NAK]#99[CAR]0998034787[CAR]
29 12:01:56.317 (0143862644) <<<  [NAK]#99[CAR]0998005147[CAR]

我期望的输出:

09:10:16.874 [CAR]0998006798[CAR]
09:10:57.048 [CAR]0998019022[CAR]
09:59:56.276 [CAR]0998016987[CAR]
10:05:36.728 [CAR]0998050310[CAR]
10:55:36.792 [CAR]099805241D[CAR]0998028452[CAR]
11:32:16.737 [CAR]0998050289[CAR]0998031483[CAR]
11:34:16.170 [CAR]0998034787[CAR]
12:01:56.317 [CAR]0998005147[CAR]

3 个答案:

答案 0 :(得分:1)

或更简单:

$Array = @()
foreach ($line in $file)
{
$Array += $line -replace '^..\s' -replace '\s\(.*\)' -replace '<<<.*#\d+'
}
$Array

答案 1 :(得分:1)

多个问题。

在循环内部,您引用$file而不是$line。在上一个操作中,您使用String.Replace()方法使用正则表达式模式 - 方法无法理解 - 请改用-replace运算符:

$file = Get-Content "C:\RS232_COM2*"

foreach($line in $file){
    $line = $line.Replace(" <<<  [NAK]#99","")
    $line = $line.Remove(0,3)

    # now use the -replace operator and output the result
    $line -replace  "\(([^\)]+)\)","" 
}

您可以在一个正则表达式替换中完成所有操作:

$line -replace '\(\d{10}\)\ <<<\s+\[NAK]\#99',''

答案 2 :(得分:1)

另一种选择是用一个正则表达式抓住你需要的一行的部分并连接它们:

$input_path = 'c:\data\in.txt'
$output_file = 'c:\data\out.txt'
$regex = '(\d+(?::\d+)+\.\d+).*?\[NAK]#99(.*)'
select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { [string]::Format("{0} {1}", $_.Groups[1].Value, $_.Groups[2].Value) } > $output_file

正则表达式是

(\d+(?::\d+)+\.\d+).*?\[NAK]#99(.*)

请参阅regex demo

<强>详情:

  • (\d+(?::\d+)+\.\d+) - 第1组:一个或多个数字后跟1个+ :和一个或多个数字的序列,然后是.,再次是1+个数字
  • .*?\[NAK]#99 - 除了换行符之外的任何0 +字符尽可能少到第一个[NAK]#99字面值字符序列
  • (.*) - 第2组:该行的其余部分

获得所有匹配后,与$_.Groups[1].Value连接的$_.Groups[2].Value会产生预期的输出。