2016-11-29 109 views
0

我试图从PowerShell的.txt文件中的多行提取某些值。我目前正在使用多个替换和删除cmd,但它不能按预期工作,并且有点太复杂。 有没有更简单的方法来做到这一点?使用PowerShell从.txt文件中的字符串提取某些值

我的脚本:

$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] 
+0

'$ result1 = $ file.replace' - >'$ result1 = $ line.replace' –

回答

1

或更为简单:

$Array = @() 
foreach ($line in $file) 
{ 
$Array += $line -replace '^..\s' -replace '\s\(.*\)' -replace '<<<.*#\d+' 
} 
$Array 
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','' 
+0

非常感谢。易于理解和很好的解释。 –

1

另一种选择是只获取一条线,你需要一个正则表达式的零件和Concat的他们:

$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[2].Value级联的$_.Groups[1].Value取得预期的输出。

相关问题