Awk实现带全局行号的文件分页浏览脚本优化需求
实现分页浏览时显示文件全局行号
要解决分页浏览时awk输出局部行号的问题,核心是直接在awk中基于原文件的全局行号过滤内容并打印,而不是先截取行再用awk重新计数。
关键修改思路
原脚本如果是通过管道(比如sed截取后传给awk)生成内容,awk会从1开始重新计数行号,导致显示局部行号。改为直接让awk处理整个文件,通过传递起始/结束行号参数,过滤出目标行并打印原文件的行号(NR变量)即可。
完整修改后的脚本
#!/bin/bash if [ $# -ne 1 ]; then echo "Usage: $0 <file>" exit 1 fi file="$1" total_lines=$(wc -l < "$file") page_lines=$(( $(tput lines) - 1 )) # 预留一行显示操作提示 start_line=1 while true; do # 计算当前页结束行号,避免超出文件总行数 end_line=$(( start_line + page_lines - 1 )) (( end_line > total_lines )) && end_line=$total_lines # 清屏并打印当前页内容(带全局行号) clear awk -v start="$start_line" -v end="$end_line" 'NR >= start && NR <= end {print NR, $0}' "$file" echo "Page: $(( (start_line - 1)/page_lines + 1 )) / $(( (total_lines + page_lines -1)/page_lines )) | h:上翻页 j:下翻页 q:退出" # 处理用户输入 read -n 1 key case "$key" in j) (( start_line + page_lines <= total_lines )) && start_line=$(( start_line + page_lines )) ;; h) (( start_line - page_lines >= 1 )) && start_line=$(( start_line - page_lines )) ;; q) clear exit 0 ;; esac done
核心代码说明
awk -v start="$start_line" -v end="$end_line" 'NR >= start && NR <= end {print NR, $0}' "$file":通过-v传递起始/结束行号,NR是awk内置的全局行号变量,直接打印它就能输出原文件的真实行号。- 边界处理:计算
end_line时判断是否超过文件总行数,避免显示空行;翻页时限制start_line在合理范围内,防止越界。
内容的提问来源于stack exchange,提问作者Valentin Luque
相关产品推荐
相关产品推荐

