4
\$\begingroup\$

I want to be able to use Bash's ^search^replace functionality in PowerShell, the closest I can come is with this function and linking it to the alias ^.

So in Bash I would do:

$ ping google.com
$ ^google^bing

And then I'd get to ping bing without re-writing the command.

In PS with this code I have to do:

> ping google.com
> ^ google^bing

The extra space isn't that big of a deal to me. However, there are some other issues that I'm not sure of how to fix.

  1. If I do a few of the search and replaces in a row, the term is found in a previous command, so it doesn't trigger the error which prevents it from running a random command. IE:
PS H:\> ^ gdsajhfgajhgjf^domain.com
    gdsajhfgajhgjf not found in previous command
...

PS H:\> ^ gdsajhfgajhgjf^domain.com
    gdsajhfgajhgjf not found in previous command
...

PS H:\> ^ gdsajhfgajhgjf^domain.com
    ping domain.com
  1. The commands that are run aren't ever entered into the PowerShell history. So while they run as one would hope, I can't go back and see the commands. I looked through the documentation for get-history, add-history and invoke-history but can't find a way to use those for anything.

  2. I'm not sure if there's better ways to do this, in general. I looked around but can't find anything that looks comparable to this functionality. It seems inelegant to me because of the way PowerShell's history works doesn't insert the command that's actually run, it just inserts ^ search^replace so I have to go back until it finds the last actual command, and then do the search/replace on that.

Anyhow, here's the code:

Function PSReplace {
    param ([string]$SearchAndReplace)

    $SearchTerm = $SearchAndReplace.split("^")[0]
    $Search = $SearchTerm
    $Replace = $SearchAndReplace.split("^")[-1]
    $CommandHistory = Get-History

    $Found = $False
    $CommandCount = -1
    $LastCommand = $CommandHistory[$CommandCount].CommandLine

    if ($LastCommand[0] -ne "^"){
        if ($LastCommand -like "*$SearchTerm*"){
            $Found = $True
        }
    }

    else{
        while ($LastCommand[0] -eq "^"){
            $CommandCount -= 1
            $LastCommand = $CommandHistory[$CommandCount].CommandLine
            $Search = $LastCommand.Split(" ")[1].split("^")[0]

            if ($LastCommand -like "*$SearchTerm*"){
                $Found = $True
            }
        }
    }

    if ($Found -eq $False){
        Throw "$SearchTerm not found in previous command"
    }

    $ReplacedCommand = $LastCommand.Replace($Search, $Replace)
    write-host $ReplacedCommand
    Invoke-Expression $ReplacedCommand
}
\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.