2

I have multiple machines uploading files to one FTP directory. The first part of the filename is the machine, the rest is a timestamp, e.g. AAAAA_20130312_125113.

Now I want to get a sorted list of all Unique machines that have uploaded to this directory. I managed to write the lost of all filenames.substring(0,5) to the host but I still don't have the unique machine names.

$files=Get-ChildItem $strMOVETO -Name -Include TAS*.csv -Recurse
ForEach ($i in $files) { Write-Host $i.Substring(0,5) }

Any hints on how to do this? Does not necessary have to be a one liner, although that would be a nice challenge ;-).

Thanks!

alroc
  • 27,574
  • 6
  • 51
  • 97
guzzisto
  • 23
  • 1
  • 3
  • As an aside: [`Write-Host` is generally the wrong tool to use](http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/), unless the intent is to write _to the display only_, thereby bypassing PowerShell's success output stream and thus the ability to send the output to other commands, capture it in a variable or redirect it to a file. That said, in PSv5+ `Write-Host` now writes to the [information stream](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection), whose output _can_ be captured, but only via `6>`. – mklement0 Apr 18 '19 at 17:05

3 Answers3

5

What happens when you have an 8-character machine name? Your substring will break. Since the machine name, date & time are delimited by an _, split on that & get the first item.

Get-ChildItem $strMOVETO -recurse -name -include TAS*.csv|%{$_.split("_")[0]}|sort-object -unique

To filter on date as well:

Get-ChildItem $strMOVETO -recurse -include TAS*.csv|where-object{$_.lastwritetime -ge (get-date).adddays(-1)}|%{$_.basename.split("_")[1]}|sort-object -unique
mklement0
  • 382,024
  • 64
  • 607
  • 775
alroc
  • 27,574
  • 6
  • 51
  • 97
  • Machine name-length is indeed variable. Assuming [1] instead of [0] would take the second item (TAS_xxxxxxxx as in the Filter), put a } before the last pipe and it is complete! Thanks – guzzisto Mar 12 '13 at 12:42
  • Can I combine this command with a Where-Object {$_.LastWriteTime -ge (Get-Date).AddDays(-1)} ?!? If I leave out the -Name tag the Split does not work, if I use the -Name tag the LastWriteTime is not available ... – guzzisto Mar 12 '13 at 12:57
  • Yes you can - see my edit. The split isn't working because now that you've omitted `-Name`, you're getting a collection of objects back, not just a list of names. – alroc Mar 12 '13 at 13:06
  • Briliant, you saved my day ;-) – guzzisto Mar 12 '13 at 13:51
  • Note that `-Name` when combined with `-Recurse` returns (relative) _paths_ rather than mere file _names_ for files located further down the subtree, in which case `$_.split("_")[0]` won't work as intended. – mklement0 Apr 18 '19 at 21:03
1

Not tested but something like this:

Get-ChildItem $strMOVETO -Name -Include TAS*.csv -Recurse | % { $_.Name.Substring(0,5) } | Sort -Unique

You don't need to do the Write-Host inside the loop and it's easier to use % instead of a foreach loop.

Dave Sexton
  • 10,768
  • 3
  • 42
  • 56
0

pipe the results of your command into a | sort -unique

$files=Get-ChildItem $strMOVETO -Name -Include TAS*.csv -Recurse
ForEach ($i in $files) { Write-Host $i.Substring(0,5) } | sort -unique

...but better still would be to simplify the script...

$filter = "TAS*.csv"
Get-ChildItem -Path $strMOVETO -Filter $filter -Recurse | % {$_.BaseName.Substring(0,5) } | sort -unique
TechSpud
  • 3,418
  • 1
  • 27
  • 35