2016-11-29 5 views
0

Im пытается извлечь определенные значения из нескольких строк внутри. TXT-файла с помощью PowerShell. В настоящее время я использую множественную замену и удаление cmd, но она не работает должным образом и слишком сложна. Есть ли более простой способ сделать это?Извлечь определенные значения из строки в .txt-файлах с помощью PowerShell

Мой сценарий:

$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[1].Value сцепляются с $_.Groups[2].Value дают ожидаемый результат.