Output Group-Object Column to File - powershell

Using Powershell I created a data set like this.
Count Name Group
----- ---- -----
2 108005 {108005, 108005}
2 114763 {114763, 114763}
2 115826 {115826, 115826}
2 115925 {115925, 115925}
2 117435 {117435, 117435}
2 114152 {114152, 114152}
2 117093 {117093, 117093}
Using this code.
$check = Get-Content $file | Group | Where {$_.count -gt 1}
I used the code to check for duplicates and cannot figure out how to output the Name column to a list in a plain txt file with only the names. There doesn't seem to be much documentation on how to do this. Is this even possible?

Use either ForEach-Object or Select-Object -ExpandProperty:
$duplicates = Get-Content $file | Group | Where {$_.count -gt 1} |Select-Object -ExpandProperty Name
Since you don't need anything other than the name, you can avoid generating the individual sets during grouping, with the -NoElement switch parameter:
$duplicates = Get-Content $file | Group -NoElement | Where {$_.count -gt 1} |Select-Object -ExpandProperty Name

Related

how to parse a value to variable using powershell from data in table format

I have command $Var1=Get-ChildItem -Attributes !Directory Statement_*.pdf | Sort-Object -Descending -Property LastWriteTime | select -First 1|Select-Object "Name" which gives me output in below format
Name
----
Statement_2022MTH05_750571314.pdf
I only want to store Statement_2022MTH05_750571314.pdf file name in a variable, so that when I fire command Write-Output $Var1 then it should print Statement_2022MTH05_750571314.pdf only. Thanks in advance.
You can use -ExpandProperty Name which will Specifies a property to select, and indicates that an attempt should be made to expand that property. So,
Select-Object -First 1 | Select-Object "Name"
can be replaced with
Select-Object -First 1 -ExpandProperty Name

powershell find newest file based on 1st 2 chars

I have files like this in folder:
C:\G1001
C:\G1002
C:\G2001
C:\G2002
C:\G2003
C:\1G001
C:\1G003
C:\1G025
How do I get the latest file based on 1st 2 chars of file name.
I need output like this (using powershell):
C:\G1002
C:\G2003
C:\1G025
You can combine Group-Object with Sort-Object:
Group the files by the first 2 chars of it's BaseName - Group-Object { -join $_.BaseName[0..1] }
Count Name Group
----- ---- -----
3 1G {/path/to/folder/1G001.ext, /path/to/folder....
2 G1 {/path/to/folder/G1001.ext, /path/to/folder....
3 G2 {/path/to/folder/G2001.ext, /path/to/folder....
For each group, sort them -Descending (from highest to lowest) and get the first one with Select-Object -First 1
Get-ChildItem path/to/files | Group-Object { -join $_.BaseName[0..1] } |
ForEach-Object {
$_.Group | Sort-Object BaseName -Descending | Select-Object -First 1
}
Example
[System.IO.FileInfo[]]$files = #'
G1001.ext
G1002.ext
G2001.ext
G2002.ext
G2003.ext
1G001.ext
1G003.ext
1G025.ext
'# -split '\r?\n'
$files | Group-Object { -join $_.BaseName[0..1] } |
ForEach-Object {
$_.Group | Sort-Object BaseName -Descending |
Select-Object FullName, Name -First 1
}
# Results in:
FullName Name
-------- ----
/path/to/folder/1G025.ext 1G025.ext
/path/to/folder/G1002.ext G1002.ext
/path/to/folder/G2003.ext G2003.ext

How do I group and sort values into a dictionary?

I'm attempting to find the latest version of multiple files within a directory. Currently, I'm calling GCI per file, but that is extremely slow, so I want to instead cache all the results by unique file name and then just perform a lookup in the cache.
I'm currently doing the following:
Gci $filePath -Recurse | ?{ -Not $_.PSIsContainer } | Group-Object Name
I'm trying to convert this to the powershell equivalent of the C# code:
group.ToDictionary(g => g.Key, g => g.Values.OrderByDescending(v => v.ModifiedAt).First().FullName)
How would I accomplish this in Powershell?
What I would do to create a hashtable of files would be to create an empty hashtable, and then populate it with the results of your GCI:
$files = ${}
GCI $filepath -Recurse -File | Group Name | ForEach{ $files.Add($_.Name, ($_.Group | Sort LastWriteTime)) }
Or if all you want is the most recent file, add | Select -Last 1 after the Sort LastWriteTime. If all you care about is the path, you could even do | Select -Last 1 -ExpandProperty FullName.
$Files = ${}
GCI $filepath -recurse | Group Name | ForEach{ $files.Add($_.Name, ($_.Group | Sort LastWriteTime | Select -Last 1 -ExpandProperty FullName)) }

Powershell - count files with same name pattern

I try to count files in a folder which have the same name pattern. In this case every signs before "_" is the important part (the pattern).
Example (c:\temp)
ct24fe_2016-03-01.txt
ct24fe_2016-03-04.txt
ct24fe_2016-03-08.txt
ct24fe_2016-04-01.txt
ct24fe_2016-04-04.txt
xye4ka_2015-03-04.txt
xye4ka_2015-03-08.txt
xye4ka_2015-03-10.txt
xye4ka_2015-03-15.txt
xye4ka_2015-04-01.txt
xye4ka_2015-04-04.txt
zzztgf_2014-04-16.txt
zzztgf_2014-04-18.txt
zzztgf_2014-04-19.txt
zzztgf_2014-05-15.txt
The result should be:
Name | Count
ct24fe | 5
xye4ka | 6
zzztgf | 4
How could I do this?
Thanks for your support.
Group-Object supports scriptblocks for the -Property argument, you can pipe the files directly to it:
Get-ChildItem C:\temp |Group-Object {$_.Name -split '_' |Select -First 1} -NoElement
So I've come up with this:
$input = "your stuff"
$array = New-Object System.Collections.ArrayList
$input | % {$array.Add($_.split("_")[0])}
$array | Group-Object -NoElement
One possibility:
(Get-ChildItem c:\temp -Name) -replace '_.*' | Group-Object -NoElement

PowerShell filtering range of file names

I am trying to write a very simple (as far as I know :-) ) script in PowerShell v2.0.
Every morning I need to look at some files to check if they are up to date.
All of the files are in the same folder.
The files are named like so: from1.rar, from2.rar from13.rar, from14.rar, from27.rar, from29.rar and so on. As you can see, the files are in different ranges. I want to filter the name of the files by a range that I determine. I suppose regex will do the trick, but I don't know how to use it...
What I have for now is just filtering and sorting all of the files by time and name into one table:
Get-ChildItem -filter "*.rar" | sort LastWriteTime -Descending | sort name | Format-Table LastwriteTime, name > C:\Users\user1\Desktop\update.txt
Now I want to break the table to form a number of groups (or smaller tables) from the names of the files.
Something like this should do the trick:
$low = 10
$high = 25
Get-ChildItem -Filter '*.rar' | ? {
$_.Name -match 'from(\d+)\.rar' -and
[int]$matches[1] -gt $low -and
[int]$matches[1] -le $high
} | ...
Demonstration:
PS C:\> $files = 'from1.rar','from13.rar','from14.rar','from27.rar','from29.rar'
PS C:\> $files
from1.rar
from13.rar
from14.rar
from27.rar
from29.rar
PS C:\> $files | ? {
>> $_ -match 'from(\d+)\.rar' -and
>> [int]$matches[1] -gt $low -and
>> [int]$matches[1] -le $high
>> }
>>
from13.rar
from14.rar
Here's one way to use a regex:
$range = 5..10
get-childitem From*.rar |
where {$range -contains ($_.name -replace 'From(\d+)\.rar','$1')}
To break your tables into groups of tables, just add the -GroupBy parameter to the cmdlet Format-Table.
For example, to create a table for each file by its property Name:
Get-ChildItem -filter "*.rar" | sort LastWriteTime -Descending | sort name | Format-Table LastwriteTime, name -GroupBy Name
But that might generate too many groups if you have many files, so you may group the table on the first letter of the Name property, like so:
Get-ChildItem -filter "*.rar" | sort LastWriteTime -Descending | sort name | Format-Table LastwriteTime, name -GroupBy #{name="First Letter";E={ ($_.name).substring(0,1) }}
Or, to group the table on the first two letters of the Name property:
Get-ChildItem -filter "*.rar" | sort LastWriteTime -Descending | sort name | Format-Table LastwriteTime, name -GroupBy #{name="First Letter";E={ ($_.name).substring(0,2) }}