Get a string using Select-String method in Powershell - powershell

I have many text files like these and below is a sample from one such file. This is part of a file File_Content12.
name:duplicate1-content:philips -sequence:primary...........
name:guard1-content:sony -sequence:primary...........
name:Linux-content:sony -sequence:third...........
name:Windows-content:IPS -sequence:secondary...........
name:Notebook-content:Mark -sequence:fourth...........
name:duplicate1-content:Tony -sequence:primary...........
I'm writing a powershell code to get the name duplicate1 when the content is sony.
I've written the below code and it gets the information as which content is present in which file, line number along with the line.
$contents = 'sony','Philips'
ForEach ($ct in $contents)
{
Get-Childitem -Path "D:\Input\Files\" | Select-String -Pattern "$ct" | Select Filename,LineNumber,Line,#{n='Content';e={$ct}}
}
I'm stuck on this part to get the name duplicate1 when the content is sony. Do I need to use the IndexOf and Substring to get the value or is there any other way to get this name.

Select-String uses Regular Expression so duplicate.*sony should do what you need
$contents = 'duplicate.*sony','Philips'
ForEach ($ct in $contents)
{
Get-Childitem -Path "D:\Input\Files\" | Select-String -Pattern "$ct" | Select Filename,LineNumber,Line,#{n='Content';e={$ct}}
}
Run Get-Help about_Regular_Expressions for more details

Related

How find a file with part of his name in PowerShell

I'm new to PowerShell and on StackOverflow.
I'm trying to write a script which gives me the Total Path to a *.pdf file,
My File Name is in a variable (I get it before with previous part of code) for example : $myVariable.Nom
After I try to find my file with this:
Get-ChildItem -Path "c:\myPath\" -Filter $myVariable.Nom
But it doesn't work. I think I have a mistake where I try to filter with my File Name in the ChildItem command but don't know how to use it correctly.
The goal is (if myVariable.Nom = "TOTO" for example) to have c:\myPath\TOTO.pdf
Can anyone help me ?
Thanks.
The -Filter parameter on Get-ChildItem supports a wildcard search using * or ?. Your code is pretty close to what you're looking for, you just need to add *.
Get-ChildItem -Path "c:\myPath\" -Filter "*$($myVariable.Nom)*"
Note that I'm using * at the beginning and end of the variable, meaning that the filter should search for any Item that contains the string in your variable.
In your example, you know that the File Name is TOTO so you could use * only at the end of the Filter:
-Filter "$($myVariable.Nom)*"
Remember that you can add the -Recurse flag on Get-ChildItem if you want to search recursively.
Now if you want to get the FullName (Total Path) you can use any of the examples below:
# Example 1
(Get-ChildItem -Path "c:\myPath\" -Filter "*$($myVariable.Nom)*").FullName
# Example 2
$var = Get-ChildItem -Path "c:\myPath\" -Filter "*$($myVariable.Nom)*"
$var.FullName
# Example 3
Get-ChildItem -Path "c:\myPath\" -Filter "*$($myVariable.Nom)*" |
Select-Object -Expand FullName
Edit
Following your second question, how to deal with a CSV with no headers:
$path = 'C:\path\to\csv.csv'
# Note: I'm using -Delimiter ';' because as you have shown,
# you are using semicolon as delimiter, however, if the delimiter
# are commas there is no need to use it.
$csv = Import-Csv $path -Delimiter ';' -Header 'Name','Qte'
# Now you can loop through it to find the files:
foreach($file in $csv)
{
$var = Get-ChildItem -Path "c:\myPath\" -Filter "*$($file.Name)*"
0..$file.Qte | foreach-object {
$var.FullName
}
}
Thank you for your answers : It's work fine !!
Now i want to improve it a litle bit : In my CSV i have 2 column : in the previous example i called the first column "Name" this is why i used myVariable.Name) for example:
Name;Qte
TOTO;1
TITI;3
Now how i can select the first column if i didn't have name on first line ?
file like this one for example :
TOTO;1
TITI;3
Thank you

powershell Parsing for multiple keywords and sending output to a text file

I'm trying to write a powershell cmdlet to find multiple words in lines in file. Example. I need to parse "word1", "word2", "word3" are in the same line of a file. I'm doing something wrong because I tried this with no success:
(gci -File -Filter FileName | Select-String -SimpleMatch word1, word2,word3) > outputFileName.txt
where FileName = name of file, outputFileName = generated file from my search of the three words. Thank you.
Select-String doesn't have any combination operator that I can think of. If your words were always in that order, then you could do -Pattern 'word1.*word2.*word3' as your match, but if they could be in any order that would get complex very quickly. Instead, I'd look at
.. | Select-String 'word1' | Select-String 'word2' | Select-String 'Word3'
so, all the lines which match word1. Out of those, the ones which match word2 somewhere. Out of that even smaller result, the ones which also match word3.
try this:
$wordlist=#("word1", "word2", "word3")
Get-ChildItem "c:\temp\" -file | %{$currentfile=$_.FullName; Get-Content $_.FullName |
%{
$founded=$true
foreach ($item in $wordlist)
{
if (!$_.Contains($item))
{
$founded=$false
break
}
}
if ($founded)
{
$currentfile
}
}
}

Get string values after a pattern using PowerShell

I want to get the string which are there after $ctrl in below html code snippet:
<div ng-if="$ctrl.CvReportModel.IsReady">
ng-click="$ctrl.confirmation()"></cs-page-btn>
<cs-field field="$ctrl.CvReportModel.Product" ng-model="$ctrl.UploadedFile.Product"></cs-field>
<cs-field field="$ctrl.CvReportModel.Month" ng-model="$ctrl.UploadedFile.Month"></cs-field>
So I am trying to get output like:
CvReportModel.IsReady
confirmation()
CvReportModel.Product
CvReportModel.Month
I am trying to do it using Get-Content and Select-String but still not able to get the desired output.
Use the Get-Content cmdlet to read your file and use a regex to fetch your desired content:
$content = Get-Content 'your_file_path' -raw
$matches = [regex]::Matches($content, '"\$ctrl\.([^"]+)')
$matches | ForEach-Object {
$_.Groups[1].Value
}
Regex:
"\$ctrl\.[^"]+
Output:
CvReportModel.IsReady
confirmation()
CvReportModel.Product
UploadedFile.Product
CvReportModel.Month
UploadedFile.Month
Another approach using the Select-String cmdlet and a regex with positive lookbehind:
Select-String -Path $scripts.tmp -Pattern '(?<=\$ctrl\.)[^"]+' |
ForEach-Object { $_.Matches.Value }
Output:
CvReportModel.IsReady
confirmation()
CvReportModel.Product
CvReportModel.Month
Note:
This will only return the first $ctrl.* match of each line. But since this matches your desired output it could be usefull for you.

Find group of words in a text file and extract the line to new text file

txt contains word "hi" "hello" "aloha" as per below
hi
hello
aloha
And I have one more file abc.txt which contains many words including the above 3 words. Now I developed a PowerShell script to search the words in abc.txt and extract the line containing the words to a new file done.txt. I use
-match command to find the word.
How to use the file ref.txt which contains the words for the finding, instead of declare the words in coding?
I would like to develop it in cmd.exe instead of PowerShell.
$source = "C:\temp\abc.txt"
$destination = "C:\temp\done.txt"
$hits = select-string -Path $source -SimpleMatch "hi","hello","aloha"
$filecontents = get-content $source
foreach($hit in $hits)
{
$filecontents[$hit.linenumber-1]| out-file -append $destination
"" |out-file -append $destination
}
This should do the batch trick:
findstr /G:ref.txt abc.txt >> done.txt
This would print all lines containing the stings in ref.txt in abc.txt to done.txt
Have I understood you question correctly?
To cover the PowerShell aspect of this question...
To get the patterns you want from file is rather easy since Select-String supports strings arrays for the -Pattern parameter. In its simplest form you could just do something like this
$patterns = Get-Content c:\temp\ref.txt | Where-Object{$_}
$hits = Select-String c:\temp\test.txt -Pattern $patterns -SimpleMatch
Your file contained a blank which I was not sure was on purpose or not. I used Where-Object{$_} to filter that out just in case. Then just pass that string array $patterns to the parameter -Pattern.
The rest of your code after that could use a little tune up. There is no need to read the source file in a second time just to output the matches again. Your output is just the matching line with a newline following.
$patterns = Get-Content c:\temp\ref.txt | Where-Object{$_}
$results = Select-String c:\temp\test.txt -Pattern $patterns -SimpleMatch
$results.Line | ForEach-Object{"$_`r`n"} | Set-Content C:\temp\out.txt
Probably not the best way to get the desired output but it should work regardless.

How to read a string from text file using powershell

I want to read a specific string from a text file and output the string into another text file.
My text file (Sample.txt) looks like below:
#{AssemblyName=Microsoft.Office.Excel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1y08bdf1111e0105c; Path=C:\Tes\app1\cc\application; ProjectPath=C:\test\application\Application.vbproj; Name=Microsoft.Office.Excel}
#{AssemblyName=System; Path=C:\Tes\app2\ser\application; ProjectPath=C:\test\application2\Application.vbproj; Name=System}
I do not want to include anything except the assemblyname.. i.e, the script should not consider version, culture etc.
The text file has lot of such assembly information.
I would like to read only the AssemblyName and write that to another text file in powersehll.
For Ex: The output.txt should contain only Microsoft.Office.Excel.
Also, I want to exclude few assembly names that start with a specific string like for eg: System. How can I do that?
I tried below, but it's not writing anything to the output.txt.
$workdir = "C:\Test"
$Txt = "$workdir\Sample.txt"
Function GetAsmName($rTxt)
{
Get-Content $Txt
$regex = '#{AssemblyName="(\w*?)"[,|;]'
$matches = (select-string -Path $Txt -Pattern $regex)
$matches | Select -Expandproperty Matches | Select #{n="Name";e={$_.Groups[1].Value}}
Set-Content -path $workdir\Output.txt -value $matches
}
Any help would be greatly appreciated.
Thanks
Try:
$workdir = "C:\Test"
$Txt = "$workdir\Sample.txt"
Function GetAsmName($rTxt)
{
$captures = gc $rTxt |
select-string -Pattern '(?<=AssemblyName=)([^;|,]*)' -allmatches |
select -expa matches | select -expa value
Set-Content -path $workdir\Output.txt -value $captures
}
GetAsmName $Txt