Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@tehishik

PowerShell の Select-String で Grep っぽく強調表示する

More than 1 year has passed since last update.

PowerShell はオブジェクトを扱えるので、Grep のように正規表現マッチで String の検索を行うことは多くないものの、たまーーにコンソール出力内容の検索したくなることがあり、ハイライトしてくれればいいのにとずっと思っていたので方法をメモ。

環境は PowerShell Core 6.2。

結果から

Before

before1.png

After

after2.png

Yay!

参考にしたスクリプト

以下の 2 つのスクリプトを参考にしました。多謝。

Get-ChildItem や Select-String の表示形式を変更するモジュール。ただし。正規表現マッチ部をハイライトする機能はない。

タイトル通り、PowerShell の既定出力である Out-Default をフックするサンプル。

Profile.ps1

以下のコードを Profile.ps1 に書けば実現できます。

function MatchInfo {
    param (
        [Parameter(Mandatory = $True, Position = 1)]
        $match
    )
    # 色の設定
    $PSColor = @{
        Default     = 'White' 
        Path        = 'Cyan' 
        LineNumber  = 'Yellow'
        Line        = 'White' 
        MatchedText = 'Red' 
        BackGround  = 'White'
    }

    # 行数表示
    Write-host $match.LineNumber -foregroundcolor $PSColor.LineNumber -noNewLine
    Write-host ":`t" -foregroundcolor $PSColor.Default -noNewLine

    # 該当行をマッチしたテキストで Split し、色を変えて出力
    $ParsedText = $match.Line -split $match.pattern
    Write-host $ParsedText[0] -foregroundcolor $PSColor.Line -noNewLine
    for ($i = 1; $i -lt $ParsedText.length; $i += 1) {
        Write-host $match.matches[0].value -foregroundcolor $PSColor.MatchedText -noNewLine
        Write-host $ParsedText[$i] -foregroundcolor $PSColor.Line -noNewLine
    }
    Write-Host
}


function Out-Default {
    [CmdletBinding(ConfirmImpact = "Medium")]
    param
    (
        [Parameter(ValueFromPipeline = $true)]
        [System.Management.Automation.PSObject] $InputObject
    )
    begin {
        $wrappedCmdlet = $ExecutionContext.InvokeCommand.GetCmdlet("Out-Default")
        $sb = { & $wrappedCmdlet @PSBoundParameters }
        $__sp = $sb.GetSteppablePipeline()
        $__sp.Begin($pscmdlet)
    }
    process {
        # 受け取ったオブジェクトが MatchInfo だった場合
        if ($_ -is [Microsoft.Powershell.Commands.MatchInfo]) {
            MatchInfo $_
        }
        # MatchInfo 以外ならパイプライン処理を続ける
        elseif (![string]::IsNullOrEmpty($_)) {
            $__sp.Process($_)
        }
    }
    end {
        $__sp.End()
    }
}
4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
tehishik

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?