Home > Enterprise >  Equivalent of `ls -t | head`
Equivalent of `ls -t | head`

Time:12-01

Intro

On Linux, I'll often use something like this to see the recently changed files in a directory with many files:

ls -t | head

I can do the following in PowerShell which is similar:

Get-ChildItem | Sort-Object -Property LastWriteTime | Select-Object -Last 15

That's a bit long so I then have the following in $PROFILE:

function Recent ()
{
    Get-ChildItem | Sort-Object -Property LastWriteTime | Select-Object -Last 15
}

And maybe also:

Set-Alias lst Recent

or

Set-Alias ls-t Recent

as a shorter variant.

Question

Is there a built-in way to list the recently changed files that's more concise than the approach I've shown above?

Is there some other best practice that y'all would recommend?

CodePudding user response:

As already presented in the comments, You can go from :

Get-ChildItem | Sort-Object -Property LastWriteTime | Select-Object -Last 15

to

gci | Sort-Object LastWriteTime |Select -l 15

What is at play ?

  • gci is an alias for Get-ChildItem. To view all aliases available, you can type Get-Alias in your current session.
  • Sort-Object LastWriteTime make use of positional arguments. When an unnamed argument is given to a Powershell cmdlet, it is mapped to the first positional parameter.
  • Select -l 15 -l stand for -last. This work because when getting a parameter that does not exist, Powershell will attempt to map it to the closest matching parameter. In all the parameter available with the Select-Object cmdlet, only -last can be matched (no other parameter for that cmdlet start with the letter L. Note that in this case, l is not defined as an alias for last. It is Powershell parameter disambiguation.

Best practices

What you do in your session stay in your session. You can use aliases, parameter disambiguation as much as you please.

That being said, when developing a script or a module, you should avoid using aliases, disambiguated parameters and positional parameter altogether.

Some kind of problems that might occurs.

Parameter disambiguation might fail if the cmdlet introduce another parameter that could also be a match. For instance Get-Service -inputObject something work well. Get-Service -in "test" will fail as it is ambiguous. -in can match -inputObject but also -include. And while Get-Service -inp "test" would work, it is not very readable compared to simply using the full parameter name.

Aliases might not be available cross-platform. For instance, while sort work as an alias for sort-object in Windows, it does not in Linux (as it is a native command there). This kind of differentiation might produce unexpected results and break your script depending on context. Also, some aliases might be dropped in the future and they do make the script less readable)

Finally, positional parameters should also be avoided in scripts & modules. Using named parameter will make your scripts more clear and readable for everyone.

To summarize, while working in a session, you can use aliases, parameter disambiguation and positional parameter as you please but when working on scripts or modules, they should be avoided.

References

Select-Object

Select-Object [-InputObject ] [[-Property] <Object[]>] [-ExcludeProperty <String[]>] [-ExpandProperty ] [-Unique] [-Last ] [-First ] [-Skip ] [-Wait] []

Types of Cmdlet Parameters

A positional parameter requires only that you type the arguments in relative order. The system then maps the first unnamed argument to the first positional parameter. The system maps the second unnamed argument to the second unnamed parameter, and so on. By default, all cmdlet parameters are named parameters.

Powershell Parameter Disambiguation and a surprise

For instance, instead of saying Get-ChildItem -Recurse, you can say Get-ChildItem -R. Get-ChildItem only has one (non-dynamic) parameter that started with the letter ‘R’.. Since only one parameter matches, PowerShell figures you must mean that one. As a side note, dynamic parameters like -ReadOnly are created at run-time and are treated a bit differently.

  • Related