首页 > 解决方案 > 如何在awk中为变量着色

问题描述

我有一个运行良好的 awk 命令:

awk '{a[$1]++}END{for(i in a){printf i"\t"a[i]"\n"}}' infile

它计算 1 美元中的重复次数。输出如下所示:

MTRFHLILLPLLFSWFSYCFG_1    1
MLAELSVAFTLAAFALA_rc_1     3

我想让输出变成红色。\033[01;31m

通常,当我想在 awk 中为输出着色时,我会这样做:

RED='\033[01;31m'
NONE='\033[0m'

awk -v r=$RED -v n=$NONE '{printf r$1n"\n"}' infile 

我用上面描述的命令尝试了这个(计算 $1 中的重复次数),但它不起作用。我认为这是因为 awk 无法将 r 和 i 识别为单独的变量,例如,在 bash 中我会使用 $r$i。是这样吗?

这是我尝试过的命令:

awk -v r=$RED -v n=$NONE '{a[$1]++}END{for(i in a){printf ri"\t"a[i]"\n"n}}' infile

输出如下所示:

1 #See how the first half of the output (i) is missed and is not coloured. 
3

任何人都可以解释为什么这不起作用并帮助我解决它吗?

谢谢

标签: awkcolors

解决方案


由于问题只是说“它不起作用”的代码而没有说明它以什么方式不起作用,所以这里列出了代码中可能导致它“不起作用”的内容:

  1. 始终引用您的 shell 变量(r="$RED", not r=$RED),请参阅https://mywiki.wooledge.org/Quotes。引号是您必须默认使用并在需要时删除的东西,而不是在需要时添加的东西。
  2. 要连接变量,您需要在它们之间留下一些分隔符。给定名为的变量r,你可以用ori连接它们,但如果你写这只是另一个名为 的变量。r i(r)(i)riri
  3. 对于任何包含输入数据的内容,始终不要这样做printf "%s", foo,因为只要包含打印格式字符(例如.printf foofoofoo%s
  4. 不要对未导出的 shell 变量使用全大写(请参阅正确的 Bash 和 shell 脚本变量大写)。
red='\033[01;31m'
none='\033[0m'

seq 3 | awk -v r="$red" -v n="$none" '{printf "%s%s%s\n", r, $1, n}'
1
2
3

对于您的其他脚本:

seq 3 | awk -v r="$red" -v n="$none" '{a[$1]++}END{for(i in a){printf "%s%s\t%s%s\n", r, i, a[i], n}}'
1       1
2       1
3       1

不清楚为什么要将颜色定义为 shell 变量并将这些值传递给 awk 而不是仅仅在 awk 中定义它们:

seq 3 | awk '
    BEGIN {
        red  = "\033[01;31m"
        none = "\033[0m"
    }
    { printf "%s%s%s\n", red, $1, none }
'
1
2
3

(上面的所有输出都是红色的,老实说!)。


推荐阅读