awk - 如何在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
任何人都可以解释为什么这不起作用并帮助我解决它吗?
谢谢
解决方案
由于问题只是说“它不起作用”的代码而没有说明它以什么方式不起作用,所以这里列出了代码中可能导致它“不起作用”的内容:
- 始终引用您的 shell 变量(
r="$RED"
, notr=$RED
),请参阅https://mywiki.wooledge.org/Quotes。引号是您必须默认使用并在需要时删除的东西,而不是在需要时添加的东西。 - 要连接变量,您需要在它们之间留下一些分隔符。给定名为的变量
r
,你可以用ori
连接它们,但如果你写这只是另一个名为 的变量。r i
(r)(i)
ri
ri
- 对于任何包含输入数据的内容,始终不要这样做
printf "%s", foo
,因为只要包含打印格式字符(例如.printf foo
foo
foo
%s
- 不要对未导出的 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
(上面的所有输出都是红色的,老实说!)。
推荐阅读
- ruby-on-rails - 可以使模块名称大写吗?
- java - Java: How can I add numbers in an If Statement (explanation in the post)
- ionic-framework - 相机插件杀死apk ionic
- swiftui - SwiftUI:UIkit UIbezier 到 SwiftUI 路径
- c# - Automapper - 将简单列表映射到复杂的嵌套类型
- reactjs - How to create unit test for URL params for React Router using Enzyme
- r - Mean Values of all columns by a specific column
- javascript - Jest can't find function in module
- javascript - Javascript loop terminates partway through when accessing a prototype function
- flutter - How to change the padding of the snackbar in flutter