I am looping through all files matching the pattern maint-*.js.
These files contains tokens in the form of __MyTokenA__, __MyTokenB__, etc...so I would like to find all of these tokens. I've tried the regex below, but it doesn't find anything.
I'd like to store the tokens in an array. What would be the correct way ?
$files = Get-ChildItem dist/main-*.js
Foreach ($file in $files)
{
$matches = $file | Select-String ', "(?:\(__\))(.*?)(?:\(__\))"' -AllMatches
echo $matches
}
I think you can simplyfy your regex, then enumerate the matches property.
$file | Select-String '__(.*?)__' -AllMatches | ForEach-Object {
$_
$_.Matches | Select-Object Value
}
Related
I have several single line xml files out of which I want to extract the contents of a particular tag <LIFNR>. I managed doing that using the following two lines of power shell:
get-content P:\Webservice\21*_*CR_d*.xml | foreach-object { $_ -replace '>', ">`r`n" } > xmls_newline.txt
get-content .\xmls_newline.txt | Select-String -Pattern '.*<\/LIFNR>'
However if I want to skip the step of creating an intermediary text file I cannot achieve the same result.
$xml = get-content P:\Webservice\21*_*CR_d*.xml | foreach-object { $_ -replace '>', ">`r`n" }
$xml | Select-String -Pattern '.*<\/LIFNR>'
or
get-content P:\Webservice\21*_*CR_d*.xml | foreach-object { $_ -replace '>', ">`r`n" } | Select-String -Pattern '.*<\/LIFNR>'
each just print the result of the string splitting in the foreach-object statement, the Select-String command is ignored.
Can somebody explain to me what is different about the latter two attempts compared to the working solution?
Get-Content outputs each line as a separate string. To emulate the same behavior, split the string after > instead of appending a linebreak:
Get-Content P:\Webservice\21*_*CR_d*.xml |ForEach-Object { $_ -split '(?<=>)' } | Select-String -Pattern '.*<\/LIFNR>'
The construct (?<=...) is a lookbehind assertion - this way, PowerShell will split on a zero-length string immediately after >
I have an directory full of LogĀ“s
My current code is
(Get-ChildItem -Path |Select-string -Pattern -AllMatches).matches.count
That will get me an 8 as output. But i want a list of all Logs with an hit and how many was in them.
Like This: "File2020.09.02 17"
How can i do that?
try something like this:
$files = Get-Childitem -Path 'C:\xyz' -File
$out = foreach ($file in $files){
$content = Get-Content $file
$matchCount = ($content | Select-String -Pattern 'xyz' -AllMatches).matches.count
[PSCustomObject]#{
Filename = $file
Matches = $matchCount
}
}
$out
Since Select-String returns MatchInfo objects with a Filename property, you can use Group-Object to group objects by Filename. Group-Object inherently counts the occurrences of any passed properties.
Select-String -Path $path -Pattern $pattern -AllMatches |
Group-Object -Property FileName | Foreach-Objecet {
"{0} {1}" -f $_.Name,$_.Count
}
Group-Object's Name property contains the value of the grouped properties. Its Count property lists the number of occurrences where those grouped properties match among the piped in objects.
You can use a hash table to track the number of hits in your files.
$tracker = #{}
Select-String -Path $path -Pattern $pattern -AllMatches | Foreach-Object {
if ($tracker.Contains($_.Filename)) {
$tracker[$_.Filename]++
} else {
$tracker[$_.Filename] = 1
}
}
$tracker.GetEnumerator() | Foreach-Object {
"{0} {1}"-f $_.Key,$_.Value
}
I am trying to extract several strings from log files. So far so good. But I don't know how to extract only the required details from that result.
Example
A log entry looks like this:
(DIAG:XMLRPC)(11:07:01 15/04/2019)(MEM:130590)(TID:3632)(USER:Administrator)(REMOTE:10.67.125.177:59032)(XmlRpc: called method 'QueryCreativeFilterInfoList'.31)
I can parse it with the the following code:
$output_file = 'C:\Copy-Test\logins.txt'
$regex = 'QueryCreativeFilterInfoList'
$files = Get-ChildItem "C:\Copy-Test\Logs"
foreach ($file in $files)
{
gc $file.FullName | select-string -Pattern $regex | Select-String -Pattern "Administrator" | Out-File -FilePath $output_file -Append
}
Now I would like to only output the data, time username but I don't know how. I saw some crazy regex stuff but that was way above of my skill level.
I would appreciate if someone could guide me on this
The easiest way would be to split the log entry string by )( delimiter and then print members of a resulting array. Something like this:
gc $file.FullName | select-string -Pattern $regex | Select-String -Pattern "Administrator"| foreach {
$a=$_ -split "\)\("
"$(($a[1] -split " ")[1,0] -join ' ') $($a[4].substring(5))"
}
I am using the following script that iterates through hundreds of text files looking for specific instances of the regex expression within. I need to add a second data point to the array, which tells me the object the pattern matched in.
In the below script the [Regex]::Matches($str, $Pattern) | % { $_.Value } piece returns multiple rows per file, which cannot be easily output to a file.
What I would like to know is, how would I output a 2 column CSV file, one column with the file name (which should be $_.FullName), and one column with the regex results? The code of where I am at now is below.
$FolderPath = "C:\Test"
$Pattern = "(?i)(?<=\b^test\b)\s+(\w+)\S+"
$Lines = #()
Get-ChildItem -Recurse $FolderPath -File | ForEach-Object {
$_.FullName
$str = Get-Content $_.FullName
$Lines += [Regex]::Matches($str, $Pattern) |
% { $_.Value } |
Sort-Object |
Get-Unique
}
$Lines = $Lines.Trim().ToUpper() -replace '[\r\n]+', ' ' -replace ";", '' |
Sort-Object |
Get-Unique # Cleaning up data in array
I can think of two ways but the simplest way is to use a hashtable (dict). Another way is create psobjects to fill your Lines variable. I am going to go with the simple way so you can only use one variable, the hashtable.
$FolderPath = "C:\Test"
$Pattern = "(?i)(?<=\b^test\b)\s+(\w+)\S+"
$Results =#{}
Get-ChildItem -Recurse $FolderPath -File |
ForEach-Object {
$str = Get-Content $_.FullName
$Line = [regex]::matches($str,$Pattern) | % { $_.Value } | Sort-Object | Get-Unique
$Line = $Line.Trim().ToUpper() -Replace '[\r\n]+', ' ' -Replace ";",'' | Sort-Object | Get-Unique # Cleaning up data in array
$Results[$_.FullName] = $Line
}
$Results.GetEnumerator() | Select #{L="Folder";E={$_.Key}}, #{L="Matches";E={$_.Value}} | Export-Csv -NoType -Path <Path to save CSV>
Your results will be in $Results. $Result.keys contain the folder names. $Results.Values has the results from expression. You can reference the results of a particular folder by its key $Results["Folder path"]. of course it will error if the key does not exist.
I am trying to find all files, which does not contains a selected string. Find files which contains is easy:
gci | select-string "something"
but I do not have an idea how to negate this statement.
You can use Where-Object;
gci | Where-Object { !( $_ | Select-String "something" -quiet) }
I'm not sure if it can be done without the foreach-object but this works:
gci |foreach-object{if (-not (select-string -inputobject $_ -Pattern "something")){$_}}
As mentionend in How do I output lines that do not match 'this_string' using Get-Content and Select-String in PowerShell?
Select-String has the NotMatch parameter.
So you could use it:
gci | Select-String -notmatch "something"
foreach($line in Get-Content .\file.txt)
{
if(findstr $line "dummyText.txt" ){
# Work here or skip here
}
else {
echo $line
}