How to read a string from text file using powershell - 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

Related

Powershell update string in each file within all sub-folders

I have a set of config files stored in each subfolder within a directory. These config files only contain a single string in the format XXX_YYYYMMDD where XXX is a number e.g. 006, 007 etc, so an example string would be 006_20150101. I want the powershell script to replace the XXX number with a new one in each of these config files. I'm using the below script to achieve that and it works fine. However, the issue is that it puts a new line character (ENTER) at the end of the string which I don't want. Any way to fix this?
$sourceDir = "C:\Users\001"
$configFiles = Get-ChildItem $sourceDir *.dat -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace "006", "007" } |
Set-Content $file.PSPath
}
By default set-content ends with a newline, use -NoNewline to not have this behavior:
Set-Content -path $file.PSPath -NoNewline
I dont know if u can use this but you can use regex replace to match the first 3 digits in the string:
$regex = "^\d{3}"
# matches any 3 digits("\d{3}") at the beginning("^") of a string
"124_20201030" -replace $regex, "007"

Get a string using Select-String method in 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

Search for Multiple strings in a text file in Powershell

I have a text 'File.txt'. There are 100's of lines.
The file contains the string 'XX' (in any line), 'YY' (in any line) and 'ZZ' (in any line).
I want to check if the text file really contains 'XX' or 'YY' or 'ZZ'. If it yes then exit the script.
I'm not sure how to give multiple search patterns in the below line Or any modification to this existing code would help.
$myString = Select-String -Path C:\Temp\File.txt -Pattern "XX"
Edited Code:
$myFile = Get-Content -Path 'C:\file.txt | Out-String
if (Select-String $myFile -Pattern 'XX|YY' -NotMatch)
{
Do something else
}
Select-String accepts a regular expression as a pattern, so you can just use a logical OR to check for all three strings:
if ( Select-String -Path C:\Temp\File.txt -Pattern 'XX|YY|ZZ' ) {
echo "yes"
# Do something else
}

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

Powershell - reading ahead and While

I have a text file in the following format:
.....
ENTRY,PartNumber1,,,
FIELD,IntCode,123456
...
FIELD,MFRPartNumber,ABC123,,,
...
FIELD,XPARTNUMBER,ABC123
...
FIELD,InternalPartNumber,3214567
...
ENTRY,PartNumber2,,,
...
...
the ... indicates there is other data between these fields. The ONLY thing I can be certain of is that the field starting with ENTRY is a new set of records. The rows starting with FIELD can be in any order, and not all of them may be present in each group of data.
I need to read in a chunk of data
Search for any field matching the
string ABC123
If ABC123 found, search for the existence of the
InternalPartNumber field & return that row of data.
I have not seen a way to use Get-Content that can read in a variable number of rows as a set & be able to search it.
Here is the code I currently have, which will read a file, searching for a string & replacing it with another. I hope this can be modified to be used in this case.
$ftype = "*.txt"
$fnames = gci -Path $filefolder1 -Filter $ftype -Recurse|% {$_.FullName}
$mfgPartlist = Import-Csv -Path "C:\test\mfrPartList.csv"
foreach ($file in $fnames) {
$contents = Get-Content -Path $file
foreach ($partnbr in $mfgPartlist) {
$oldString = $mfgPartlist.OldValue
$newString = $mfgPartlist.NewValue
if (Select-String -Path $file -SimpleMatch $oldString -Debug -Quiet) {
$stringData = $contents -imatch $oldString
$stringData = $stringData -replace "[\n\r]","|"
foreach ($dataline in $stringData) {
$file +"|"+$stringData+"|"+$oldString+"|"+$newString|Out-File "C:\test\Datachanges.txt" -Width 2000 -Append
}
$contents = $contents -replace $oldString $newString
Set-Content -Path $file -Value $contents
}
}
}
Is there a way to read & search a text file in "chunks" using Powershell? Or to do a Read-ahead & determine what to search?
Assuming your fine isn't too big to read into memory all at once:
$Text = Get-Content testfile.txt -Raw
($Text -split '(?ms)^(?=ENTRY)') |
foreach {
if ($_ -match '(?ms)^FIELD\S+ABC123')
{$_ -replace '(?ms).+(^Field\S+InternalPartNumber.+?$).+','$1'}
}
FIELD,InternalPartNumber,3214567
That reads the entire file in as a single multiline string, and then splits it at the beginning of any line that starts with 'ENTRY'. Then it tests each segment for a FIELD line that contains 'ABC123', and if it does, removes everything except the FIELD line for the InternalPartNumber.
This is not my best work as I have just got back from vacation. You could use a while loop reading the text and set an entry flag to gobble up the text in chunks. However if your files are not too big then you could just read up the text file at once and use regex to split up the chunks and then process accordingly.
$pattern = "ABC123"
$matchedRowToReturn = "InternalPartNumber"
$fileData = Get-Content "d:\temp\test.txt" | Where-Object{$_ -match '^(entry|field)'} | Out-String
$parts = $fileData | Select-String '(?smi)(^Entry).*?(?=^Entry|\Z)' -AllMatches | Select-Object -ExpandProperty Matches | Select-Object -ExpandProperty Value
$parts | Where-Object{$_ -match $pattern} | Select-String "$matchedRowToReturn.*$" | Select-Object -ExpandProperty Matches | Select-Object -ExpandProperty Value
What this will do is read in the text file, drop any lines that are not entry or field related, as one long string and split it up into chunks that start with lines that begin with the work "Entry".
Then we drop those "parts" that do not contain the $pattern. Of the remaining that match extract the InternalPartNumber line and present.