Is there a way to refer to the second last word of the previously entered command (like $^ for the first and $$ for the last word)

Viewed 59

In PowerShell, when entering a command, I can refer to the value of the first and last word of the most recently entered command with $^ and $$. I am wondering if there is a shortcut to refer to the second last, nth last or nth word also.

1 Answers

There's no direct equivalent to the automatic variables you mention, but you can combine Get-History with PowerShell's language parser (System.Management.Automation.Language.Parser) to achieve your intent:

function Get-PrevCmdLineTokens {

  # Get the previous command line's text.
  $prevCmdLine = (Get-History)[-1].CommandLine

  # Use the language parser to break it into syntactic elements.
  $tokens = $null
  $null = [System.Management.Automation.Language.Parser]::ParseInput(
    $prevCmdLine, 
    [ref] $tokens,
    [ref] $null   
  )

  # Get and output an array of the text representations of the syntactic elements,
  # (excluding the final `EndOfInput` element).
  $tokens[0..($tokens.Count - 2)].Text
 
}

Example:

PS> $null = Write-Output Honey "I'm $HOME"
PS> Get-PrevCmdLineTokens

The above yields:

$null
=
Write-Output
Honey
"I'm $HOME"

Note:

  • As with $^ and $$, the tokens that make up the command are unexpanded, meaning that they are represented as typed rather than by their interpolated value.

  • However, unlike with $^ and $$, any syntactic quoting is retained (e.g., "I'm $HOME" instead of I'm $HOME).

    • While you could use .Value instead of .Text in the function above in order to strip the syntactic quoting, you would then miss out on tokens such as $null and =.
Related