Display Multiple pipeline Values Of Same Get-Content - powershell

I am trying to get the string value in csv file.
$path = "product.csv"
Get-Content $path | Select-String -AllMatches -Pattern "[^\x00-\x79]"
I successfully grab the string, however I wish display the line numbers then the string values.
Example Output:
LineNo String
1 a
2 b
3 c
I did successfully grab the linenumber using below command. How should I combine the command with the first command so the output will be alike the example output?
Get-Content $path | Select-String -AllMatches -Pattern "[^\x00-\x79]" | Select-Object LineNumber

If you want the entire line, select the Line property:
... |Select-Object LineNumber,Line
If you only want the part of the line that was matched by the pattern, you'll need a calculated property to grab the Value from the Matches property:
... |Select-Object LineNumber,#{Name='String';Expression={$_.Matches.Value}}

Related

Powershell script to sum only specific records from file(s)

I am trying to work with a directory full of files.
I want to find specific rows within the file,
from those rows, extract a numeric value
and them sum up all these values, for all values, in a directory.
It would look like this...
File1.txt
bread:123
ham:456
eggs:789
File2.txt
bread:999
mayo:789
eggs:123
and so on...
I want to find the row with eggs, extract the number, and sum these numbers together across files.
I found this script from other posts but it's only segements, I still have trouble understanding how to use and pipe/ variables /braces.
dir . -filter "*.txt" -Recurse -name | foreach{(GC $_).Count} | measure-object -sum
#?
Get-Content | Select-String -Pattern "eggs*"
#?
$record -split ":"
I want the script to say "eggs = 912" which would be 123 + 789 = 912
Here is a possible solution:
$pattern = 'eggs'
$sum = Get-ChildItem . -File -Recurse -Filter *.txt |
Get-Content |
Where-Object { $_ -match $pattern } |
ForEach-Object { ($_ -split ':')[1] } |
Measure-Object -Sum |
ForEach-Object Sum
"$pattern = $sum"
Output:
eggs = 912
Get-ChildItem finds all files recursively that match the filter
Get-Content reads each line of every file and passes that on in the pipeline
Where-Object includes only lines that match the given RegEx pattern
The ForEach-Object line splits the line at : and extracts the sub string, which is at array index [1].
Measure-Object accumulates all numbers (it converts strings to double, if necessary). Internally, it creates a variable in its begin block, accumulates the pipeline input to this variable in its process block and outputs the variable value in its end block.
The last ForEach-Object line is necessary because Measure-Object actually outputs an object with a Sum property, but we only want the value of that property, not the entire object. If you'd remove that line you'd have to write "$pattern = $($sum.Sum)" instead, to access the Sum property of the sum object.
You can treat the as csv files. import-csv doesn't take wildcards for the filename.
import-csv file1.txt,file2.txt -Delimiter : -Header item,amount |
where item -eq eggs | measure -sum amount
Count : 2
Average :
Sum : 912
Maximum :
Minimum :
StandardDeviation :
Property : amount

Powershell Select-String Problem with variable

I have a CSV list of numbers that I would like to use Select-String to return the name of the file that the string is in.
When I do this
$InvoiceList = Import-CSV "C:\invoiceList.csv"
Foreach ($invoice in $InvoiceList)
{
$orderFilename = $FileList | Select-String -Pattern "3505343956" | Select Filename,Pattern
$orderFilename
}
It gives me a response, I realize it is in a loop, but it gives me a response (albeit many times). This is what I would like.
Order# 199450619.pdf.txt 3505343956
Order# 199450619.pdf.txt 3505343956
But, when I run this:
$InvoiceList = Import-CSV "C:\invoiceList.csv"
Foreach ($invoice in $InvoiceList)
{
$orderFilename = $FileList | Select-String -Pattern "$invoice" | Select Filename,Pattern
$orderFilename
}
or this
$InvoiceList = Import-CSV "C:\invoiceList.csv"
Foreach ($invoice in $InvoiceList)
{
$orderFilename = $FileList | Select-String -Pattern $invoice | Select Filename,Pattern
$orderFilename
}
I get nothing in return.
I know there is data in $invoice because if I just ouput $invoice, I get all the invoice numbers that are in the CSV.
What am I doing wrong?
Since $InvoiceList contains the output from a Import-Csv call, it contains custom objects with properties named for the CSV columns, not strings.
Therefore, you must explicitly access the property that contains the invoice number (as a string) in order to use it as search pattern with Select-String.
Assuming that the property / column name of interest is InvoiceNum (adjust as needed):
Foreach ($invoice in $InvoiceList.InvoiceNum) { # Note the .InvoiceNum
$FileList | Select-String -Pattern $invoice | Select Filename,Pattern
}
Note:
Even though $InvoiceList contains an array of objects, PowerShell allows you to access a property that only exists on the elements of the array (.InvoiceNum here), and get the elements' property values as a result - this convenient feature is called member-access enumeration.
However, note that Select-String's -Pattern parameter accepts an array of search patterns, so you can shorten your command as follows, which also improves performance:
$FileList |
Select-String -Pattern (Import-Csv C:\invoiceList.csv).InvoiceNum |
Select-Object Filename,Pattern

How can I write the output of Select-String in powershell without the line numbers?

I am using powershell to filter a textfile using a regular expression. To do that I am using the following command:
Select-String -Pattern "^[0-9]{2}[A-Z]{2}[a-z]{5}" -CaseSensitive rockyou.txt > filter.txt
The issue however, when writing them to filter.txt it's preceding the matched strings with the name of the original file followed by the line numbers e.g.:
rockyou.txt:12345:abcdefg
rockyou.txt:12345:abcdefg
rockyou.txt:12345:abcdefg
How can I make it so that it ommits the line numbers?
Select-String outputs an object per match, and each has a Line property containing the original line in which the match occurred. You can grab only the Line value, like so:
... |Select-String ... |Select-Object -ExpandProperty Line |Out-File filter.txt
This way seems to work. Set-content saves the string version of the matchinfo object without any extra blank lines, as opposed to out-file or ">".
get-content rockyou.txt | select-string '^[0-9]{2}[A-Z]{2}[a-z]{5}' -ca |
set-content filter.txt
get-content filter.txt
01ABcdefg
It occurred to me you might still want the filename:
select-string '^[0-9]{2}[A-Z]{2}[a-z]{5}' rockyou.txt -ca |
% { $_.filename + ':' + $_.line } > filter.txt
cat filter.txt
rockyou.txt:01ABcdefg

Powershell Select-String parse email from .rtf to .csv

Parse .rtf file, output email addresses in .csv file?
I have an .rtf file containing a bunch of email addresses, I need this parsed so that I can compare a .csv file to active users in Active Directory.
Basically I want what is to the left of "#my.domain.com"
$finds = Select-String -Path "path\to\my.rtf" -Pattern "#my.domain.com" | ForEach-Object {$_.Matches}
$finds | Select-Object -First 1 | ft *
This of course gives me one result so that I don't have alot of output.
I only manage to get matches or the complete line.
I've tried adding something along the line of
$finds = Select-String -Path "path\to\my.rtf" -Pattern "\w.#my.domain.com"
This gives me the very two last letters in the addresses.
If I keep adding dots to the "wildcard"
-Pattern "\w.....#my.domain.com"
I also get a ton of numbers/characters (.rtf formatting) for addresses that contains fewer characters.
How do I do this?
EDIT: I will update the question as soon as I've found a solution. As of now I'm trying with regular expressions.
Example:
-Pattern "\w*?#my.domain.com"
$mPattern = "[a-zA-Z0-9._%+-]+#[a-zA-Z0-9.-]+(\.[a-zA-Z]{2,4})"
$lines = get-content "path\to\your.rtf"
foreach($line in $lines){
([regex]::MAtch($rtfInput, $mpattern, "IgnoreCase ")).value }
This code worked for me. My inital code but with a new search pattern.
$finds = Select-String -Path "path\to\my.rtf" -Pattern "[a-zA-Z0-9._%+-]+#[a-zA-Z0-9.-]+(\.[a-zA-Z]{2,4})" | ForEach-Object {$_.Matches}
$finds | Select-Object -First 10 | ft *
Thanks!

.matches in powershell not returning any results

I'm working on a script that is based off of a cryptography script on blog.commandlinekungfu.com. Essentially I want to get the frequency of all of the letters in a text file. In the example, he uses Here-String to store the values, but I want to use Get-Content. Here's the breakdown.
This code works
PS c:\$foobar = #"
foo
bar
"#
PS c:\$foobar | Select-String -AllMatches "[A-Z]").matches
It returns the approriate values. However, if I have a text file that contains exactly the same information, I get a null value returned.
PS c:\$text = Get-Content "foobar.txt"
PS c:\$text | Select-String -AllMatches "[A-Z]").matches
Returns nothing
Does anyone know why a Here-String works but not Get-Content?
The here string is treated as one string, with get-content you pipe a collection of strings. You can pipe the filoe content to the Out-String cmdlet:
(get-content file.txt | out-string | Select-String -AllMatches "[A-Z]").matches