0

Im trying to extract certain values from multiple lines inside a .txt file with PowerShell. Im currently using multiple replace and remove cmd's but it doesn't work as expected and is a bit too complex. Is there a more simple way to do this?

My script:

$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 file:

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]

The output i expect:

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]
1
  • $result1 = $file.replace -> $result1 = $line.replace Commented Nov 29, 2016 at 11:47

3 Answers 3

1

or more simple:

$Array = @()
foreach ($line in $file)
{
$Array += $line -replace '^..\s' -replace '\s\(.*\)' -replace '<<<.*#\d+'
}
$Array
Sign up to request clarification or add additional context in comments.

Comments

1

Another option is to just grab the parts of a line you need with one regex and concat them:

$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

The regex is

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

See the regex demo

Details:

  • (\d+(?::\d+)+\.\d+) - Group 1: one or more digits followed with 1+ sequences of : and one or more digits, then . and again 1+ digits
  • .*?\[NAK]#99 - any 0+ chars other than newline as few as possible up to the first [NAK]#99 literal char sequence
  • (.*) - Group 2: the rest of the line

After we get all matches, the $_.Groups[1].Value concatenated with $_.Groups[2].Value yield the expected output.

Comments

1

Multiple issues.

Inside the loop you reference $file rather than $line. In the last operation, you're using the String.Replace() method with a regex pattern - something that method doesn't understand - use the -replace operator instead:

$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  "\(([^\)]+)\)","" 
}

You could do it all in one regular expression replacement:

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

1 Comment

Thank you very much. Easy to understand and good explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.