入力色付きの列を使用するには?

入力色付きの列を使用するには?

入力色を使用すると、熱出力を妨げるようです。なぜこれが起こり、もっと重要なのは解決策がありますか?

$ {
  echo "$(tput bold)foo$(tput sgr0)" "$(tput bold)bar$(tput sgr0)"
  echo bar foo
} | column -t
foo  bar
bar                     foo

macosとubuntu 20.04で問題を再現しましたが、どちらもBSD列を使用しているようです。

答え1

パイプを使用すると、cat -vそのファイルストリームのすべての文字を表示できます。column幅を計算するために使用します。

^[[1mfoo^[(B^[[m ^[[1mbar^[(B^[[m
bar foo

正しいアプローチは、すべてのコンテンツ生成をすべての形式(MVCモデルなど)から分離することです。タブなどの出力を生成するためにスペースが追加されるため、column内容が変更されます。また、tput端末にコマンドを追加します。これらの操作を分離することで、出力をファイルに保存したり、フォーマット機能から渡したり、コンソールに送信したり、他のターゲット用にフォーマットしたりできます。


しかし、幅の計算から特定の文字を除外するのもawk良い練習です。column -t以下で使用する正規表現は多くをtput捉えますが、すべてではないことはほとんど確信しています。

$ cat tst.awk
BEGIN {
    OFS = "  "
}

{
    nr = NR
    for (i=1;i<=NF;i++) {
        f[NR,i] = $i
        gsub(/\x1B[^[:alpha:]]+[[:alpha:]]/,"",$i)
        if (length($i) > col[i]) col[i] = length($i)
    }
}

END {
    for (i=1;i<=nr;i++) {
        for (j=1;j<=length(col);j++) {
            printf "%-"col[j]"s%s", f[i,j], (j==length(col)? ORS : OFS)
        }
    }
}

次に、最初の出力をパイプに接続します。awk -f tst.awk

答え2

${
    echo -e "$(tput 太字)foo$(tput sgr0)" "$(tput 太字)bar$(tput sgr0) baz";
    エコバリッチ;
  } |猫-v
^[[1mfoo^[(B^[[m ^[[1mbar^[(B^[[m baz))
豊富なバー

問題はtput sgr0、ご存知のように、基本的にtputsエスケープコードが環境変数から取得された端末タイプに基づいて使用されることですTERM

これにより:

infocmp -1 |grep -E 'bold|sgr0'
    bold=\E[1m,
    sgr0=\E(B\E[m,

あなたは何を見るでしょうか?勇敢なそしてsgr0コードはANSIではなくエスケープ値であり、forおよびforcat -vに変換した後に出力からわかるように、コマンドは同じ操作を実行し、ANSIエスケープタイプコードで解決されますが、存在し続けると失敗して認識されません。 ANSIからエスケープされ、最終出力が期待どおりに正しく劣化しなくなります。^[[1mtputs bold^[(B^[[msgr0column(B^[(B^[[m

これにより:

infocmp -1 -T ansi |grep -E 'bold|sgr0'
        bold=\E[1m,
        sgr0=\E[0;10m,

それぞれに同等のANSIエスケープコードを見つけることができるので、これを解決するための2つのオプションがあります。

  1. tputs上記のANSIエスケープコードに置き換えてください。

    { 
      echo -e "\033[1mfoo\033[0;10m" "\033[1mbar\033[0;10m baz";
      echo bar foo;
    } |column -t
    
  2. 端末タイプを次に渡しますtputs

    {
      echo -e "$(tput bold)foo$(tput -T ansi sgr0)" "$(tput bold)bar$(tput -T ansi sgr0) baz";
      echo bar foo;
    } |column -t
    

答え3

columnUbuntu 18.04を実行していますが、期待どおりに動作しない動作が原因で混乱しています。他の人が提案したように、問題は倉庫にアンティークがあるということです。

最新バージョンを入手する唯一の方法は次のとおりです。util-linux買戻契約

-Vまだインポートバージョンが追加されていないため、これを理解するのは難しいです!おそらくよりエレガントな方法があります。しかし、man column下の日付を「2004年7月29日」と指定しておおよそのバージョンを推論しました。比較する2004年マンページ到着2019年マンページ。前者は単に説明していますが、4つオプション、後者はほとんど2つのダース

また、MacOS Catalinaでも同じ結果が得られたと言えます。brew最新バージョンを含むパッケージが見つかりませんが、columnおそらくどこかに隠されているでしょう。

最新バージョンにアクセスできない場合は、既存のバージョンに対応するマニュアルページを確認する必要があります。そうしないと、状況が苦しくなる可能性があります!

関連情報