如何利用Bash的read工具在用户输入时自动添加日期时间格式标点?
命令行实现日期时间输入时自动插入分隔符
问题描述
我在脚本中用以下代码提示用户输入日期时间:
printf "Please insert start of time window in format YYYY-MM-DD HH:MM:SS: " read startDatetime
想实现用户输入时动态插入日期的短横线、日期与时间间的空格以及时间的冒号,类似网页端JavaScript的效果,但需要命令行解决方案,查阅read手册的分隔符选项后没找到办法。
解决方案
bash的read命令本身没有直接的自动插入分隔符功能,但可以借助bash的readline特性(通过bind命令绑定自定义按键处理函数)来实现。以下是完整的脚本示例:
#!/bin/bash # 定义自动插入分隔符的函数 auto_insert_separators() { local input=${READLINE_LINE} local pos=${READLINE_POINT} # 只保留数字,过滤掉已有的分隔符 input=$(echo "$input" | tr -d '- :') # 根据输入长度构建带分隔符的字符串 case ${#input} in 1|2|3|4) # 年份部分,无分隔符 formatted=$input ;; 5|6) # 年份-月份 formatted="${input:0:4}-${input:4}" ;; 7|8) # 年份-月份-日期 formatted="${input:0:4}-${input:4:2}-${input:6}" ;; 9|10|11|12) # 年份-月份-日期 小时 formatted="${input:0:4}-${input:4:2}-${input:6:2} ${input:8}" ;; 13|14) # 年份-月份-日期 小时:分钟 formatted="${input:0:4}-${input:4:2}-${input:6:2} ${input:8:2}:${input:10}" ;; *) # 年份-月份-日期 小时:分钟:秒(最多14位数字) formatted="${input:0:4}-${input:4:2}-${input:6:2} ${input:8:2}:${input:10:2}:${input:12:2}" ;; esac # 计算光标位置:原光标位置加上插入的分隔符数量 local sep_count=0 if (( ${#input} >=5 )); then ((sep_count++)); fi if (( ${#input} >=7 )); then ((sep_count++)); fi if (( ${#input} >=9 )); then ((sep_count++)); fi if (( ${#input} >=13 )); then ((sep_count++)); fi if (( ${#input} >=15 )); then ((sep_count++)); fi # 确保光标位置不超过格式化后的字符串长度 local new_pos=$(( pos + sep_count )) if (( new_pos > ${#formatted} )); then new_pos=${#formatted} fi READLINE_LINE="$formatted" READLINE_POINT="$new_pos" } # 绑定所有数字按键到自定义函数 for key in {0..9}; do bind -x '"\'$key'": auto_insert_separators' done # 提示用户输入并读取 printf "Please insert start of time window in format YYYY-MM-DD HH:MM:SS: " read -e startDatetime # 恢复默认的数字按键绑定(可选,避免影响后续脚本操作) for key in {0..9}; do bind '"\'$key'": self-insert' done # 输出结果验证 echo "You entered: $startDatetime"
关键说明
- 核心逻辑:自定义函数
auto_insert_separators会在用户按下数字键时,过滤输入中的非数字字符,再根据输入的数字长度自动插入对应的分隔符(-、空格、:)。 read -e:启用readline编辑模式,确保绑定的按键事件能被触发。bind命令:将0-9的数字按键绑定到自定义函数,每次输入数字时自动执行分隔符插入逻辑。- 光标位置处理:计算插入分隔符后的光标位置,保证光标始终跟随输入位置,提升交互体验。
- 恢复绑定:脚本最后恢复数字按键的默认行为,避免影响后续脚本的交互操作。
替代方案
如果觉得bash原生实现过于复杂,也可以使用第三方工具rlwrap结合自定义过滤脚本,但需要先安装rlwrap。不过原生bash方案无需额外依赖,更适合脚本部署。
内容的提问来源于stack exchange,提问作者AWSnell
相关产品推荐
相关产品推荐

