一部のデータを取得するためにコマンドラインを使用しています(カール)、関連フィールド抽出(アッ)形式を指定し(柱)。
見苦しいですがうまくいきます(しかし、すべてのスクリプトは「長くて醜い」1行)しかし、特定の色をリストしようとすると間違っています。
これは単純な(単純化された)バージョンです。働く:
curl "http://webservices.rm.ingv.it/fdsnws/event/1/query?lat=42.35&lon=13.4&maxradius=5.0&starttime=2016-01-01T00:00:00&endtime=2016-12-31T23:59:59&minmag=5&format=text&orderby=time-asc" 2>/dev/null \
| awk 'BEGIN { FS= "|"; OFS= "|" } {print $1, $2, $5, $10, $11, $13}' \
| column -t -s '|'
今、いくつかのフィールドに下線を引いていくつかを追加したいと思います。ANSIエスケープコードまったく:
curl "http://webservices.rm.ingv.it/fdsnws/event/1/query?lat=42.35&lon=13.4&maxradius=5.0&starttime=2016-01-01T00:00:00&endtime=2016-12-31T23:59:59&minmag=5&format=text&orderby=time-asc" 2>/dev/null \
| awk 'BEGIN { FS= "|" ; OFS= "|" } \
$13~/Rieti/||/Perugia/ {$13="\033[1;31m"$13"\033[0m"} \
$11~/[0-9]+/ && $11 > 5.8 {$11="\033[1;33m"$11"\033[0m"}
{print $1, $2, $5, $10, $11, $13 }' \
| column -t -s '|'
ソートが正しくありません(図を参照)。
なぜ?どうすれば解決できますか?
修正する
私はこの質問を見たことがあります列コマンドとカラーエスケープコードに関する問題しかし、彼の答えはフルカラーラインの場合に適用されるので、私の問題を解決することはできません。
私の場合、次の理由で回答を適用または調整することはできません(またはできません)。
- 問題は、後続の列に関係なく、$ 11の列が着色された場合に制限されます。
- カラーコードを追加する良い方法やエレガントな方法は見えません。後ろに柱。
テストのために列の出力をawkに送信する場合は、フィールドを適切に分離するようにawkに指示する方法がわかりません(フィールドがより多くのスペースで区切られている場合は正規表現を使用できますが、場合によっては区切りが単一のスペースで、awkフィールドを区切ります。記号で単語間のスペースとスペースを認識する方法がわかりません。
私が見ることができる唯一のことは、リセットカラーコードを割り当てから印刷ブロックに移動することです。最初出力専用バージョンのように、行間隔がより良いです(下の\033[0m
2番目のコマンドラインの下線を参照)。
ではどうやって解決しますか?私のように着色するよりエレガントな方法がありますか?
(私は知っています。Perlラインを使用するとより良いことができますが、問題があると思います。)
ベストアンサー1
この問題を解決するには3つの簡単な方法があります。
- 同じ長さを維持するには、常にこの列にエスケープシーケンスを使用してください。
- エスケープ文字を独自の列(追加の4列)に入れます。ただし、これにより、出力に余分なスペースが追加されます。
column
提案どおりにフォーマットしてください。
その他の注意事項はここにあります。ANSIエスケープコードを含む入力データを「表にする」ためのシェルツール。
最初のオプションでは、\033[1;31m
redだけを使用する代わりに\033[31;1m
redを使用し、\033[31;0m
前のコード、または同じシーケンスのコードも取り消す「赤ではない」、または通常のゼロコードを使用してください。これにより、すべての列のエスケープコードの長さが等しくなります。
BEGIN { FS=OFS="|" }
function colour(ss,cc) { return "\033[" cc ";1m" ss "\033[0m"; }
function notcolour(ss,cc) { return "\033[" cc ";0m" ss "\033[0m"; }
{
if ($13~/(RI|PG)/) { $13=colour($13,31) }
else { $13=notcolour($13,31) }
if (($11+0) > 5.8) { $11=colour($11,33) }
else { $11=notcolour($11,33) }
print $1, $2, $5, $10, $11, $13
}
(ソースデータの変更と一致するなど、いくつかのマイナーな簡略化と修正も上記に適用されました。)
このアプローチの問題は、column
合計によって異なりますlibc
。 (私はutil-linux-2.23.2から来ました。)印刷できないコンテンツが見つかった場合、column
実際の幅ではなく戻りコードは-1になります。wcswidth()
これは実際にテーブル形式を混乱させます。 util-linux-2.30.1 の最新バージョンは新しいバージョンを使用します。図書館問題を解決するが印刷できないコンテンツを16進符号化バージョンに置き換えてそれを行います。\x
したがって、元のエスケープが完全に失われます。 // エレガントでない方法で修正できます。
curl ... | awk ... | column -t -s '|' | while read -r line; do printf "$line\n"; done
printf
脱出を説明する場所。同じ効果を得る\033
には、独自のコードに置き換えることができます。\\x1b
Linuxを使用しているかどうかはわかりません。 )
3番目のオプションでは、出力区切り記号の設定をcolumn
サポートする必要があり、デフォルトは2つのスペースです。-o
""に設定すると、|
次のことができます。
curl ... | column -t -s "|" -o "|" | awk '
BEGIN { FS="|" }
function colour(ss,cc) { return sprintf("\033[%i;1m%s\033[0m",cc,ss) }
{
if ($13~/(RI|PG)/) { $13=colour($13,31) }
if (($11+0) > 5.8) { $11=colour($11,33) }
print $1, $2, $5, $10, $11, $13
}'
ここでの秘密は、column
パイプで区切られた入力を使用することです。そして出力すると、幅が固定され、awk
すべての重要なスペースを保存しながらを使用して安全に処理できます。column
サポートしていない場合は、-o
以下を使用して偽にすることができます。
curl ... | sed -e 's/|/^|/g' | column -t -s^ | awk ...
これは区切り文字を " ^|
"に倍増し、をcolumn
使用し^
、awkusesを使用します|
。これにより、仮説が^
データに確実に存在しなくなります。ハードタブが機能する可能性があります。
今「理由」を知っていると思います。しかし、明確に申し上げれば、次のようになります。
column
strlen()
wcslen()
/が端末に表示されている長さと一致しないオクテット(または文字)を素早く計算できますcolumn
長さを計算するために使用することisprint()
ができ、端末エスケープにも正しくありません。column
印刷できないコンテンツが見つかると、すべての列が削除される可能性があります(私の場合と同じように)。
カラーコードシーケンスを削除することはかなり簡単な問題ですが、column
。