【问题标题】:Bash - Number color based on sign, tabbedBash - 基于符号的数字颜色,选项卡式
【发布时间】:2018-01-10 17:05:55
【问题描述】:

我在终端中有这样的行

8  XLM      3.85  -10.18  -32.94   0.00003836      0.564      0.470    8.402
9  MIOTA   -0.60   -3.38  -11.22    0.0002438      3.582      2.986    8.300
10 DASH     0.55   -2.01   -6.55    0.0742421   1090.820    909.358    7.102
11 NEO     -0.40   -0.88   27.09   0.00832249    122.280    101.938    6.626
12 TRX      7.33  -18.68   42.45   0.00000791      0.116      0.097    6.369

如果 3,4,5 字段是正数,我想将它们打印为绿色,如果它们是负数,我想打印成红色。我正在使用 awk 和 printf,但不能同时使用 printf 的颜色和正确的制表符。

如果我像 awk 一样添加颜色代码

awk '{ if($3<0){$3="\033[0;31m"sprintf("%.2f",$3)"\033[0;0m"} else {$3="\033[0;32m"sprintf("%.2f",$3)"\033[0;0m"};}1'

然后制表符丢失或混乱。

没有颜色的完整命令是

curl -s "https://api.coinmarketcap.com/v1/ticker/?convert=EUR&limit=20" | jq -r '.[] | [.rank, .symbol, .percent_change_1h, .percent_change_24h, .percent_change_7d, .price_btc, .price_usd, .price_eur, .market_cap_eur] | @tsv' | awk '{ $3=sprintf("%.2f",$3); $4=sprintf("%.2f",$4); $5=sprintf("%.2f",$5); $6=sprintf("%.8f",$6); $7=sprintf("%.2f",$7); $8=sprintf("%.2f",$8); $9=sprintf("%.3f",$9/(1*10^9)) }1' | xargs printf '%2s %-5s %7s %7s %7s %12s %10s %10s %8s\n' 'r' 'curr' '1d' '24h' '7d' 'btc' 'usd' 'eur' 'mcap B'

【问题讨论】:

  • 管道结果到column -t ?
  • 我试过了,但我无法控制单元格对齐,而且它不像 printf 那样可读

标签: awk colors terminal printf tabular


【解决方案1】:

您的字段间距正在被修改,因为您正在修改一个字段,导致 awk 重新编译记录,用 OFS 值替换输入空格 (IFS)。如果您更改整个记录而不是任何单个字段,则 awk 不会更改字段之间的间距:

使用 GNU awk 进行 gensub():

$ cat tst.awk
BEGIN { red="\033[0;31m"; green="\033[0;32m"; norm="\033[0;0m" }
{
    for (i=3; i<=5; i++) {
        $0 = gensub("(([^[:space:]]+[[:space:]]+){"i-1"})([^[:space:]]+)", "\\1" ($i < 0 ? red : green) "\\3" norm,1)
    }
    print
}

或使用任何 awk:

$ cat tst.awk
BEGIN { red="\033[0;31m"; green="\033[0;32m"; norm="\033[0;0m" }
{
    for (i=3; i<=5; i++) {
        sub("([^[:space:]]+[[:space:]]+){"i-1"}", "&" ($i < 0 ? red : green))
        sub("([^[:space:]]+[[:space:]]+){"i-1"}[^[:space:]]+", "&" norm)
    }
    print
}

$ awk -f tst.awk file
8  XLM      3.85  -10.18  -32.94   0.00003836      0.564      0.470    8.402
9  MIOTA   -0.60   -3.38  -11.22    0.0002438      3.582      2.986    8.300
10 DASH     0.55   -2.01   -6.55    0.0742421   1090.820    909.358    7.102
11 NEO     -0.40   -0.88   27.09   0.00832249    122.280    101.938    6.626
12 TRX      7.33  -18.68   42.45   0.00000791      0.116      0.097    6.369

所以你可以看到颜色:

【讨论】:

  • ??? 非常感谢!我对正则表达式有点迷茫。我想你正在用一个颜色字符和一个无颜色字符包装第 i 个字段。但我不明白它是如何工作的。为什么要使用双方括号,什么是 i-1 匹配?是一些 awk 自定义正则表达式来匹配第 i 个字段还是一般都可以工作? ?
  • [:space:] 是一个字符类。 [[:soace:]] 是包含字符类[:space:] 的括号表达式。谷歌这些条款。 [^[:space:]]+[[:space:]]+ 是一系列非空格,后跟一系列空格。 ([^[:space:]]+[[:space:]]+){2} 是非空格后跟空格的 2 次重复(即匹配每个输入行的前 2 个字段+空格)。 i 是当前字段编号 3、4 或 5。i-1 比该数字小 1,因此当 i=3 "([^[:space:]]+[[:space:]]+){"i-1"}" 匹配到字段 3 之前。您问“一般都可以工作” - 取决于“一般”是什么意思
  • 再次感谢,现在很清楚 :) “一般”我的意思是 {i-1} 是否是 awk 特定的正则表达式语法,但在阅读您的解释后,我认为它不是 awk具体的。
猜你喜欢
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多