如何实现按指定列号切换文本前景色的Shell函数?
修复Shell函数:实现多行文本分区域变色打印
需求说明
实现Shell函数marinex-ndic,功能如下:
- 接受两个参数:第一个为切换列号(从该列开始切换颜色),第二个为多行字符串
- 每行文本的开头部分(到指定列号前一列)用蓝色粗体打印
- 从指定列号开始的后续文本用白色粗体打印
- 每行结束后重置终端格式为默认
示例调用:
str=" marinex-dgrul-blue Digit-white marinex-ltrul-blue Letter-white marinex-nmrul-blue Numeric-white" marinex-ndic 23 "$str"
执行后,每行前22列(如marinex-dgrul-blue )显示蓝色粗体,从第23列开始的内容(如Digit-white)显示白色粗体。
原始问题代码
用户编写的函数无法实现需求,原代码如下:
marinex-ndic () { ## 显示带颜色的内容和标签 local -r rst="$( tput sgr0 )" # Default Graphic Rendition local -r blu="$( tput bold; tput setaf 39 )" # BLUE local -r wht="$( tput bold; tput setaf 15 )" # WHITE printf '%s\n' "$@" \ | while IFS="" read -r vl; do printf '%s%s%s%s%s\n' "${blu}" "$vla" "$wht" "$vlb" "${rst}" done }
原代码问题点
- 未区分参数:第一个参数是列号,却被直接当作文本输出
- 未定义变量
$vla、$vlb,导致无内容输出 - 未实现按指定列号拆分文本的逻辑
- 未处理空行,会输出多余的空格式行
修正后的函数代码
marinex-ndic() { # 检查参数数量 if [ $# -ne 2 ]; then echo "用法: marinex-ndic <切换列号> <多行字符串>" return 1 fi local -r col="$1" local -r text="$2" # 终端格式控制:重置、蓝色粗体、白色粗体 local -r rst="$(tput sgr0)" local -r blu="$(tput bold; tput setaf 39)" local -r wht="$(tput bold; tput setaf 15)" # 逐行处理文本,跳过空行 printf '%s\n' "$text" | while IFS="" read -r line; do # 跳过空行 [ -z "$line" ] && continue # 拆分文本:前col-1列用蓝色,剩余用白色 local blue_part="${line:0:$((col-1))}" local white_part="${line:$((col-1))}" # 输出带颜色的文本 printf '%s%s%s%s%s\n' "$blu" "$blue_part" "$wht" "$white_part" "$rst" done }
代码说明
- 参数校验:先检查是否传入2个参数,否则提示用法
- 变量定义:将列号和文本分别存储为局部变量,颜色控制使用
tput保证跨终端兼容性 - 逐行处理:用
printf输出文本并通过管道逐行读取,跳过空行避免无效输出 - 文本拆分:使用Shell字符串截取语法
${string:start:length},其中:${line:0:$((col-1))}:从第0位开始,截取col-1个字符(对应前col-1列)${line:$((col-1))}:从第col-1位开始截取剩余所有字符(对应从第col列开始的内容)
- 颜色拼接:按蓝色部分→白色部分→重置格式的顺序输出,确保每行结束后终端格式恢复默认
内容的提问来源于stack exchange,提问作者Dilna
相关产品推荐
相关产品推荐

