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' } }