Home > OS >  regex can't be first element for pipeline - how get match
regex can't be first element for pipeline - how get match

Time:02-01

I have a regular expression that is run at the windows 10 command line, and get the error:

Expressions are only allowed as the first element of a pipeline.

I'm not sure how to put this together with the match part in the first element.

This is the document content (with important parts shown...there are multiple Manufacturer and S/N's but I just need the specific one):

e:\temp\details.txt:

...
  Manufacturer: SGSS
  S/N: A791D734804

...

I successfully get the above two lines of code from the document with this powershell, but I'm having trouble extracting the serial number after the semicolon.

This works to extract the Manufacturer and S/N lines (Context part gets line after pattern match too):

powershell "Get-Content e:\temp\details.txt | select-String -Pattern SGSS -Context 0,1" 

However, I'm trying to return just the serial number (), and get the error above. This is where I get the error with the match/command:

powershell "Get-Content -Raw e:\temp\details.txt | select-String -Pattern SGSS -Context 0,1 | $_ -match '(?ms)(N:\s)(([a-zA-Z0-9]) )'"

I tested that the regular expression works in a regex tester:

(N:\s)(([a-zA-Z0-9]) )

I used this example for the match , but I can't put it first in the expression (like the example) because of the other things I'm doing. What do you recommend?

Update: Example document contents:

A00232473244B

USB xController
RootHub
Port[6] USB Reader
Manufacturer: Gen 
S/N: 0A0000002071



Intel(R) 8 Series/1234 Series 
RootHub
Port[1]Standard-USB-Hub


USB x Controller
RootHub
Port[1] abc Printer
Manufacturer: guess
S/N: A2622431

Port[2] SG
Manufacturer: SGSS
S/N: A791B634801

Update2:

I tried this regex in a regex tester and it's still only finding the first S/N line but not following ones or just the SGSS one I care about:

S\/N:\s([a-zA-Z0-9] )[\n\r\S\s]*

Update3: Some things I tried that are returning nothing:

powershell -command Get-Content e:\temp\details.txt -Raw ^| Where{$_ -match '(?ms)SGSS[\r\n\s]*S\/N: (\S )\b'} ^| ForEach-Object { $Matches[1]}

powershell -command Get-Content e:\temp\details.txt -Raw ^| Where{$_ -match '(?ms)SGSS[\r\n\s]*S\/N: (\S )\b'} ^| ForEach-Object { echo $Matches[1]}

powershell -command Get-Content e:\temp\details.txt -Raw ^| Where{$_ -match '(?ms)SGSS[\n\r]S\/N:\s([\w]*)'} ^| ForEach-Object { echo $Matches[1]}

powershell -command Get-Content e:\temp\details.txt -Raw ^| select-string -Pattern 'SGSS[\n\r]S\/N:\s([\w]*)' ^| ForEach-Object { echo $Matches[1]}

powershell -command Get-Content e:\temp\devices.txt -Raw ^| Where{$_ -match '(?ms)SGSS[\r\n\s]*S/N: (\S )\b'} ^| ForEach-Object { $Matches[1]}

Update4:

I tried this and it's still returning nothing, with no errors as well. It's possible the issue is newlines/spaces. I'm not sure.

powershell -Command Get-Content 'e:\temp\details.txt' ^| Foreach-Object { if($_ -match 'SGSS') {$Found=1}; if(($_ -match 'S/N:\s([a-zA-Z0-9] )[\n\r\S\s]*') -and ($Found -eq 1)) {$_ -replace '^.*N:\s' }}

CodePudding user response:

You can use Where-Object and the automatic $Matches variable in a ForEach-Object scriptblock to get what you want:

powershell -command Get-Content e:\temp\details.txt -raw ^| Where{$_ -match '(?ms)SGSS[\r\n\s]*S/N: (\S )\b'} ^| ForEach-Object {$Matches[1]}

Updated to escape the pipes and fix quoting issue.

CodePudding user response:

Perhaps you could try setting a flag variable and then act on next match of your pattern. This was tested against a test file of your details.txt example above. It correctly selected your SGSS S/N#. I did alter it slightly so that on successful match of "SGSS", it just removed the "S/N: " text.

Here is the multi-line formatting. If you compose it single-line you will need the semi-colon in the ForEach-Object block, I believe.

powershell -Command Get-Content 'e:\temp\details.txt' | 
    Foreach-Object {
        if($_ -match 'SGSS') { $Found = 1 };
        if(($_ -match 'S\/N:\s([a-zA-Z0-9] )[\n\r\S\s]*') -and ($Found -eq 1)) { $_ -replace '^.*N:\s' }
    }

And Single-Liner:

powershell -Command Get-Content 'e:\temp\details.txt' ^| Foreach-Object { if($_ -match 'SGSS') { $Found = 1 }; if(($_ -match 'S\/N:\s([a-zA-Z0-9] )[\n\r\S\s]*') -and ($Found -eq 1)) { $_ -replace '^.*N:\s' } }
  • Related