表にしたい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
非表化に注意してください。
そのようなコマンドはないと思います。手作業で行う必要があります。何かのようなもの:
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]]
}
}'
興味のある人のために、私はこのawkスクリプトを StéphaneChazelasの回答 から採用しました。 $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]]
}
}
問題はもちろん、column
が印刷文字と非印刷文字を区別しないことです。bash
はそのプロンプト(PS1
)で\[ \]
エスケープ機能を使用してこれを回避します、私はそれを正確に行う他の何も知りません。
問題のあるフィールドが行のstartにあるので、すばやく厄介なハックを試しました。それをthenendですが、一般的なユーティリティを使用して簡単に解決できない同様のパディング/配置の問題が発生します。
ls -l --color | rev | column -t | rev # not a useful solution
Perl HTML::FromANSI
モジュールをインストールしている場合は、便利なansi2html
スクリプトがあります。
ls -l --color | ansi2html -f
途中までしか到達できません。HTML出力を調整する必要があります...
HTMLを中間として使用する簡単な(少し重い)ソリューションがあります。HTMLテーブルのレイアウトは、事実上、あなたがやろうとしていることです。
これはAndre Simonの ansifilter を使用します。例:
ls -l --color | ansifilter -fH
これにより、ANSIシーケンスがHTML(<span style="..."></span>
)に変換され、elinksのようなテキストモードのANSI対応ブラウザを使用してダンプできます。
不完全なHTMLが問題になる場合は、オプションで hxclean
または htmltidy
を実行して、ブラウザに渡す前にHTMLをクリーンアップできます。
ls -l --color | ansifilter -fH | Perl table.pl | elinks -dump -dump-color-mode 1
elinksまたはw3mfor this
table.pl
スクリプトは空白で分割し、関連するHTMLテーブルタグを追加して、目的のフォーマットを実現します。
print "<table>\n";
while (<>) {
print "<tr><td>" .
join("</td><td>", split(/((?!<[^>]+)\s+(?![^<]+>))/) ) .
"</td></tr>\n";
}
print "</table>\n";
justは空白で分割せず、 '<' '>'山括弧の内側にない空白で分割するので ' t <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カラー出力をサポートしていません。
いくつかのsed
作業でうまくいくでしょう:
sed
は、ANSIカラーコードを削除します
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
スペースをタブに置き換えるためのsed
sed -r "s/\s+/\t/g"
最後に:
printf "\033[0;32;1mgreen_Apple\033[0m 1 100
orange 20 19
pineapple 1000 87
avocado 4 30" \
| sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" \
| sed -r "s/\s+/\t/g"
出力:
green_Apple 1 100
orange 20 19
pineapple 1000 87
avocado 4 30
[〜#〜] ps [〜#〜]:私はこれらすべてをls --color output
で正直にテストしました。これは、エコーで遊ぶよりも簡単です。
ANSIカラーコードの削除について:
フルーツ名に_
文字と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/^[^ ]+ +//" )"
色付きの出力– onlygreen_Appleは色で表示されます。
green_Apple 1 100
orange 20 19
pineapple 1000 87
avocado 4 30