ANSIエスケープコードを含む入力データを「表にする」ためのシェルツール

ANSIエスケープコードを含む入力データを「表にする」ためのシェルツール

私の入力には、テーブルとして書きたいANSIカラーコードが含まれています。出力の色を維持したいので、表形式の出力はANSIカラーコードを維持する必要があります。だから、無邪気にそれらを剥がすことは私には合いません。

たとえば、この入力の場合

\033[0;32;1mgreen_apple\033[0m 1 100
orange 20 19
pineapple 1000 87
avocado 4 30

私が期待する結果は次のようになります。

green_apple 1    100
orange      20   19
pineapple   1000 87
avocado     4    30

上記の出力では、「green_apple」は、入力カラーコード(緑など)に従って色を付ける必要があります。私はこれを達成する方法を知りたいです。

その列を試しましたが、ANSIコードを処理しません。出力

echo '\033[0;32;1mgreen_apple\033[0m 1 100
orange 20 19
pineapple 1000 87
avocado 4 30' | column -t

残念ながら

green_apple  1     100
orange                  20    19
pineapple               1000  87
avocado                 4     30

表形式ではないことに注意してください。

答え1

そのような命令はなく、手動で行う必要があると思います。それは次のとおりです。

awk '
  {
    nf[NR]=NF
    for (i = 1; i <= NF; i++) {
      f[NR,i] = $i
      gsub(/\033\[[0-9;]*[mK]/, "", $i)
      len[NR,i] = l = length($i)
      if (l > max[i]) max[i] = l
    }
  }
  END {
    for (n = 1; n <= NR; n++) {
      for (i = 1; i < nf[n]; i++)
        printf "%s%*s", f[n,i], max[i]+1-len[n,i], ""
      print f[n,nf[n]]
    }
  }'

答え2

興味のある方のために、このawkスクリプトを適用しました。Stefan Chazerasの答え。これをコンピュータに配置し、$PATHコマンドラインから実行できる必要があります。

たとえば、

> echo -e '\e[32mHello\e[0m,World\nFoo,Bar' | colorcolumn FS=',' OFS=' | '
Hello | World
Foo   | Bar
#!/usr/bin/awk -f
#
# colorcolumn - Like `column`, but works with ANSI colors
#
# Based on this Stack Exchange answer by Stephane Chazelas:
#     https://unix.stackexchange.com/a/121139/259233

{
    nf[NR]=NF
    for (i = 1; i <= NF; i++) {
        cell[NR,i] = $i
        gsub(/\033\[([[:digit:]]+(;[[:digit:]]+)*)?[mK]/, "", $i)
        len[NR,i] = l = length($i)
        if (l > max[i]) max[i] = l
    }
}
END {
    for (row = 1; row <= NR; row++) {
        for (col = 1; col < nf[row]; col++)
            printf "%s%*s%s", cell[row,col], max[col]-len[row,col], "", OFS
        print cell[row,nf[row]]
    }
}

答え3

もちろん、問題はcolumn印刷文字と印刷されない文字を区別することではありません。この問題をプロンプト()とエスケープ機能で解決するには、bash他の方法がわかりません。PS1\[ \]

問題ドメインが次の場所にあると仮定すると、スタートその行の次に進みます。終わりただし、一般的なユーティリティを使用して簡単に解決できない同様のパディング/ソートの問題に直面します。

ls -l --color | rev | column -t  | rev   # not a useful solution

Perlモジュールがインストールされている場合は、HTML::FromANSI便利なスクリプトがありますansi2html

ls -l --color | ansi2html -f

これは戦闘の半分だけをもたらした。これでHTML出力をソートする必要があります...

HTMLを中間に配置する単純な(少し重いですが)ソリューションがあります。 HTMLテーブルのレイアウトは実際に望むものです。

これは以下を使用します。アンドレ・サイモン~のアンチフィルター、例えば:

ls -l --color | ansifilter -fH

これはANSIシーケンスをHTML(<span style="..."></span>)に変換し、これはテキストモードANSIをサポートするブラウザで使用できます(例:電子リンク

不完全なHTMLが問題の場合は、次を実行することを選択できます。hxcleanまたはhtmltidyHTMLをブラウザに渡す前に削除してください。

ls -l --color  | ansifilter -fH | perl table.pl | elinks -dump -dump-color-mode 1 

あなたは利用可能でなければなりません電子リンクまたはw3m そのために

スクリプトtable.plはスペースに分割し、関連するHTMLテーブルタグを追加して目的の形式を取得します。

print "<table>\n";
while (<>) { 
    print "<tr><td>" . 
      join("</td><td>", split(/((?!<[^>]+)\s+(?![^<]+>))/) ) . 
      "</td></tr>\n"; 
}
print "</table>\n";

しかし、実際にはそうではありません。ただスペースに分割すると、「<"">」山かっこ内ではなくスペースに分割されるため、タグが壊れません<span>。これはHTMLを解析する良い方法ではありませんが、ここで制限された入力タイプには十分です。

デフォルトの色を設定またはオーバーライドするか、ファイルに追加するには(私がそうでした)必要があるかもしれません~/.elinks/elinks.conf

set document.colors.use_document_colors = 1
set document.colors.text = "#000000"
set document.colors.background = "#ffffff"

最新(0.12.x)elinkを使用してください。以前のバージョンはANSIカラー出力をサポートしていません。

答え4

フルーツ名には、_およびalphabetic文字のみが含まれているとします。

c='(\e|\\033)\[[0-9;]+m'
sed -r "s/^($c)?([a-zA-Z_]+)($c)?/& \3/" file | column -t | 
sed -r "s/^($c[a-zA-Z_]+$c)( +)([a-zA-Z_]+)/\5\4\1/" |
sed -r "s/^[^ ]+ +//"

出力:

\033[0;32;1mgreen_apple\033[0m  1     100
orange       20    19
pineapple    1000  87
avocado      4     30

出力をカラーで表示するには(テストprintf管路渡すシェルコマンドの置換、例えば:

c='(\e|\\033)\[[0-9;]+m'; printf "$(
sed -r "s/^($c)?([a-zA-Z_]+)($c)?/& \3/;" file | column -t | 
sed -r "s/^($c[a-zA-Z_]+$c)( +)([a-zA-Z_]+)/\5\4\1/" |
sed -r "s/^[^ ]+ +//" )"

カラーで出力 –ただ グリーンアップルカラーで表示されます。

green_apple  1     100
orange       20    19
pineapple    1000  87
avocado      4     30

関連情報