如何用awk实现更完善的表格格式化?现有方案存在列格式问题
问题
现有一段Shell脚本,通过grep递归检索指定路径下匹配指定模式的内容,随后用awk将结果格式化为表格,再通过column -t进一步处理。但处理后PATTERN列中的单词会被制表符拆分,不符合预期。请问有没有更完善的awk表格格式化方法?
当前脚本代码:
main() { read -p "Enter a full path for search: " path read -p "Enter a pattern to search for: " pattern printf "\n" # Use process substitution to capture the grep output output=$(grep -inR "$pattern" "$path") if [ -n "$output" ]; then # Use awk to format the output into a table-like view echo "$output" | awk -F: 'BEGIN { printf "%-100s %-5s %-20s\n", "FILE", "LINE", "PATTERN" printf "%-100s %-5s %-20s\n", "----", "----", "-------" } { printf "%-100s %-5s %-20s\n", $1, $2, $3}' | column -t else echo "No matching results found." fi }
当前输出:
FILE LINE PATTERN ---- ---- ------- /home/user/shell-scripting-ex/Shell-scripting/scripts/new/grep_usage.sh 32 # Main function /home/user/shell-scripting-ex/Shell-scripting/scripts/new/grep_usage.sh 72 # Call the main function /home/user/shell-scripting-ex/Shell-scripting/scripts/new/random_number_generator.sh 32 # Main function /home/user/shell-scripting-ex/Shell-scripting/scripts/new/random_number_generator.sh 37 # Call the main function
解决方案
问题根源
column -t会将所有连续空白(空格、制表符等)视为列分隔符,导致PATTERN列内的空格被误判,拆分了原本连续的内容。- 原awk脚本仅提取
$3字段,若匹配行本身包含冒号,$3之后的内容会丢失,导致PATTERN列内容不完整。
改进后的脚本
main() { read -p "请输入要搜索的完整路径: " path read -p "请输入要搜索的模式: " pattern printf "\n" # 直接通过管道传递grep输出,避免变量捕获的换行处理问题 grep -inR "$pattern" "$path" | awk -F: ' BEGIN { # 定义可调整的列宽,适配不同终端 file_col = 80 line_col = 6 pattern_col = 60 printf "%-*s %-*s %-*s\n", file_col, "FILE", line_col, "LINE", pattern_col, "PATTERN" printf "%-*s %-*s %-*s\n", file_col, "----", line_col, "----", pattern_col, "-------" } { # 拼接$3到最后一个字段,恢复完整的匹配行内容 full_pattern = "" for (i=3; i<=NF; i++) { full_pattern = full_pattern (i==3 ? "" : ":") $i } # 直接用awk格式化输出,无需依赖column printf "%-*s %-*s %-*s\n", file_col, $1, line_col, $2, pattern_col, full_pattern } ' || echo "未找到匹配结果。" }
改动说明
- 移除
column -t:改用awk的%-*s格式控制列宽,彻底避免空白被误判为列分隔符的问题。 - 恢复完整内容:通过循环拼接
$3到$NF的所有字段,解决匹配行含冒号时内容丢失的问题。 - 动态列宽:用变量定义列宽,可根据终端窗口大小灵活调整。
- 简化流程:直接通过管道传递grep输出,无需先捕获到变量,避免换行符处理异常。
正确输出示例
FILE LINE PATTERN ---- ---- ------- /home/user/shell-scripting-ex/Shell-scripting/scripts/new/grep_usage.sh 32 # Main function /home/user/shell-scripting-ex/Shell-scripting/scripts/new/grep_usage.sh 72 # Call the main function /home/user/shell-scripting-ex/Shell-scripting/scripts/new/random_number_generator.sh 32 # Main function /home/user/shell-scripting-ex/Shell-scripting/scripts/new/random_number_generator.sh 37 # Call the main function
内容的提问来源于stack exchange,提问作者Avocado
相关产品推荐
相关产品推荐

