【问题标题】:How to use ANSI color codes to print colored text to bash terminal from a file?如何使用 ANSI 颜色代码将彩色文本从文件打印到 bash 终端?
【发布时间】:2021-12-04 18:56:51
【问题描述】:

我有一个像这样的文件(file.txt):

Yes
Yes
No
No

我想将此文件输出到 bash 终端,其中“是”为绿色,“否”为红色。我编写了以下脚本:

RED='\033[0;31m'
NC='\033[0m'
GREEN='\033[0;32m'

cat file.txt | sed 's/No/${RED}No${NC}/g' | sed 's/Yes/${GREEN}Yes${NC}/g' > color_file.txt

printf "$(cat color_file.txt)"

输出如下:

${GREEN}Yes${NC}
${GREEN}Yes${NC}
${RED}No${NC}
${RED}No${NC}

而不是被着色。

如果我有这样的脚本,着色工作:

RED='\033[0;31m'
printf "${RED}No${NC}"

如何读取文件,为其内容着色,然后打印到终端?

【问题讨论】:

  • 我不明白你在这里的意思。据我所知,我的报价不是问题(我可能错了,但我还很新)。问题是我不确定如何让printf 读取文件的内容并因此执行其中的命令。
  • As far as I can tell my quotes are not the issue 您的报价是问题所在。 '" 不同。研究它们之间的区别。此外,\033(4 个字符,\033)对于 printf 是特殊的,但对于 sed 则不是。 printf "$(cat color_file.txt)" 你为什么要printf $(..)?用 shellcheck 检查你的脚本。

标签: bash ansi-colors


【解决方案1】:

如何读取文件,为其内容着色,然后打印到终端?

您可以将扩展保留在文件中,并在读取文件时将 ${...} 表单替换为变量:

RED=$'\E[0;31m'
NC=$'\E[0m'
GREEN=$'\E[0;32m'
sed 's/No/${RED}No${NC}/g ; s/Yes/${GREEN}Yes${NC}/g' file.txt > color_file.txt
( export RED NC GREEN ; envsubst color_file.txt )

但我相信您实际上想将转义序列输出到文件中:

RED=$'\E[0;31m'
NC=$'\E[0m'
GREEN=$'\E[0;32m'
sed "s/No/${RED}No${NC}/g ; s/Yes/${GREEN}Yes${NC}/g" file.txt > color_file.txt
cat color_file.txt

或者您可能希望 printf 解释文件内容中的 escpe 序列:

RED='\033[0;31m'
NC='\033[0m'
GREEN='\033[0;32m'
sed "s/No/${RED}No${NC}/g ; s/Yes/${GREEN}Yes${NC}/g" file.txt > color_file.txt
printf "%b\n" "$(cat color_file.txt)"
# or maybe:
xargs -0 printf "%b" < color_file.txt
# or maybe:
sed 's/\\033/\e/g' color_file.txt 
# etc.

使用 shellcheck 检查您的脚本 - 它会告诉您您所犯的所有错误。

's/No/${RED}...'

变量扩展不在单引号内扩展。

#If you would:
RED='\033[0;31m'
.... sed "....${RED}..."

sed 不解释八进制转义序列。对于sed,字符串\033 是一个零字节0x00,后跟两个33

printf "$(cat ...)"

是一种反模式。只需执行cat ...

cat ... | sed..

是猫的无用用途。

如何让printf读取文件内容

无法读取带有printf 的文件。这不是一个工具。

并因此执行其中的命令。

这感觉与您的问题无关,但要执行文件只需使用解释器 sh ./file.sh 调用它或在当前执行环境 . ./file.sh 中获取它。

【讨论】:

  • 感谢您将转义序列输出到文件中完美运行:) 我将来会使用 shellcheck。
【解决方案2】:

我碰巧有一个方便的 bash 函数来为文本着色,而不必记住神秘的 ANSI 转义或什么值映射到什么数字。使用它:

#!/usr/bin/env bash

# Map color names to terminfo setaf/setab codes.
declare -A colors=( [black]=0 [red]=1 [green]=2 [yellow]=3 [blue]=4
                    [magenta]=5 [cyan]=6 [white]=7 )

# colorize colorname text
# Returns text wrapped in ANSI color tags. Unknown color names are mapped to white.
colorize() {
    printf "%s%s%s" "$(tput setaf "${colors[$1]:-7}")" "$2" "$(tput op)"
}

greenyes=$(colorize green Yes)
redno=$(colorize red No)
sed -e "s/Yes/$greenyes/g" -e "s/No/$redno/g" file.txt

将彩色的file.txt 打印到标准输出。您可以重定向到不同的文件,或者通过管道将其发送到 tee 或其他任何您想要的文件,同时执行这两项操作。

【讨论】:

    猜你喜欢
    • 2010-09-22
    • 1970-01-01
    • 2011-07-22
    • 2013-10-18
    • 1970-01-01
    • 2012-09-28
    • 2017-07-17
    • 2016-08-17
    相关资源
    最近更新 更多