Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to group Get-ChildItem -Recurse results in one output table?

Tags:

powershell

I'm using the following Powershell command:

Get-ChildItem -Recurse *.txt

But if there's multiple results the output will be like this:

    Directory: C:\TestFolder\myfolder\

Mode          LastWriteTime   Length Name
----          -------------   ------ ----
-a---     d/m/yyyy hh:MM PM   1234   dragons.txt

    Directory: C:\TestFolder\anotherfolder\

Mode          LastWriteTime   Length Name
----          -------------   ------ ----
-a---     d/m/yyyy hh:MM PM   66550  jabberwocky.txt

But I want to get grouped results in some form.

Maybe like this:

Mode          LastWriteTime   Length Directory                     Name
----          -------------   ------ ---------                     ----
-a---     d/m/yyyy hh:MM PM   1234   C:\TestFolder\myfolder\       dragons.txt
-a---     d/m/yyyy hh:MM PM   66550  C:\TestFolder\anotherfolder\  jabberwocky.txt

Or this:

Length  FullPath
------  --------
1234    C:\TestFolder\myfolder\dragons.txt
66550   C:\TestFolder\anotherfolder\jabberwocky.txt

You probably get the idea. How can I accomplish this, preferably in a simple and elegant manner?

I tried Get-ChildItem -Recurse *.txt | Format-Table but that doesn't do much. I've also checked the most relevant similar questions suggested by Stack Overflow (i.e. "Recurse with PowerShell's Get-ChildItem", and others), but haven't been able to distill a solution so far.


Addendum:

I used help group and found that group is actually the exact alias for the Cmdlet I thought I was looking for: Group-Object. If I do this:

Get-ChildItem -Recurse *.txt | Group-Object "FullName"

I get:

Count   Name           Group
-----   --------       -----
    1   C:\TestFold... {C:\TestFolder\myfolder\dragons.txt}
    1   C:\TestFold... {C:\TestFolder\anotherfolder\jabberwocky.txt}

But this requires me to simplify with an additional step to:

Get-ChildItem -Recurse *.txt | Group-Object "FullName" | Select-Object "Name"

Which gets:

Name
----
C:\TestFolder\myfolder\dragons.txt
C:\TestFolder\anotherfolder\jabberwocky.txt

If I really want extra properties, then I guess I want to "group on multiple properties", making the question effectively a duplicate of this other SO question.

However, all this "grouping" seems like overkill. Is there not a direct way of using Get-ChildItem to get the output I want?

like image 331
Jeroen Avatar asked Oct 02 '15 12:10

Jeroen


People also ask

Which cmdlet formats the output as table with the selected properties in columns?

The Format-Table cmdlet formats the output of a command as a table with the selected properties of the object in each column. The object type determines the default layout and properties that are displayed in each column.

What are the cmdlets that can send the output to different file formats?

The Out-File cmdlet is most useful when you want to save output as it would have displayed on the console. For finer control over output format, you need more advanced tools.

Which cmdlet is used to filter results based on Property values?

The Where-Object cmdlet is a handy way to filter objects. In this tutorial, you will learn different ways to construct a Where-Object command, it's available parameters, syntax, as well as how to use multiple conditions like a pro!

How do I use AutoSize in PowerShell?

If you specify the AutoSize parameter when you run the Format-Table command, PowerShell calculates column widths based on the actual data displayed. This makes the columns readable. The Format-Table cmdlet might still truncate data, but it only truncates at the end of the screen.


2 Answers

PowerShell has its own way of displaying System.IO.DirectoryInfo and System.IO.FileInfo objects. If you don't want to see that then you just need to use Select-Object.

Get-ChildItem -Recurse c:\temp | select Mode,LastWriteTime,Length,Directory,Name

Group-Object is completely unnecessary. Given your need I suppose Group-Object seemed appealing but its power is not needed here like it is used for in the linked question. What you really wanted to do is change how PowerShell deals with those objects. Format-Table does not work for the same reason. It was taking the PowerShell by design output and making a table. If you called the properties with Format-Table you would have the same solution as we did with Select-Object.

Get-ChildItem -Recurse c:\temp | Format-Table Mode,LastWriteTime,Length,Directory,Name

Please... Please... don't use that line if you intend to use the output in other functions. Format-cmdlets break objects and are used for the purpose of displaying data only.

like image 98
Matt Avatar answered Oct 16 '22 09:10

Matt


If you are just trying to get a list of files recursively with their fullpath names, don't use Group or Select. All of these Commands pretends to be a spreadsheet of objects displayed in a text console.

Instead use the foreach-object operator "%{ }" to dump the raw string date to the console. Example:

Get-ChildItem -Recurse *.txt | %{ $_.fullname }

(Incidentally the above is equivalent to linux command: "find .")

If you want to see which fields are accessible from the foreach-object script block. you can issue this command:

Get-ChildItem my_filepath  | get-member

Alternatively, you could pipe the output of Get-ChildItem to Export-Csv command and open it in notepad.

Get-ChildItem -Recurse -file *.txt | 
Select FullName | 
Export-Csv "files.csv"

notepad files.csv

Alternatively, use cmd:

cmd /c dir /b /s *.txt
like image 38
Bimo Avatar answered Oct 16 '22 09:10

Bimo