awk/printf数字格式化异常:多位数左移一位问题求助
解决数字带千位分隔符时的对齐问题
你用这段代码对目录大小数字做左填充对齐:
input="/home/user_install/folders_LIST_SIZES_MY_FOLDERS.txt" while IFS= read -r line ; do sudo du -sm $line | LC_NUMERIC=fr_FR.UTF8 awk '{printf "% 11 '\''d : %s\n", $1 , $2}' done < "$input"
预期的对齐效果是所有数字右对齐(比如 155 283前面有4个空格),但实际结果里,带千位分隔符的数字会向左偏移,比如 155 283前面只有2个空格,无法和其他数字对齐。
问题原因
核心问题是多字节千位分隔符的宽度计算差异:
- 设置
LC_NUMERIC=fr_FR.UTF8后,awk会用U+202F(窄不换行空格)作为千位分隔符,这个字符在UTF-8中占3个字节。 - 部分awk版本(比如mawk)的
printf宽度按字节数而非字符数计算,导致带千位分隔符的字符串总字节数超过11,系统会自动减少前缀空格数量适配,最终造成视觉偏移。
修复方案
推荐使用支持多字节字符宽度计算的gawk,确保格式化按字符数对齐。修改后的代码如下:
input="/home/user_install/folders_LIST_SIZES_MY_FOLDERS.txt" while IFS= read -r line ; do sudo du -sm "$line" | LC_NUMERIC=fr_FR.UTF8 gawk '{printf "% 11'\''d : %s\n", $1, $2}' done < "$input"
如果系统默认awk就是gawk,直接用awk即可(通常gawk会链接到awk)。如果还是有问题,可以手动实现千位分隔符格式化,确保对齐:
input="/home/user_install/folders_LIST_SIZES_MY_FOLDERS.txt" while IFS= read -r line ; do sudo du -sm "$line" | awk ' function format_num(n) { gsub(/[0-9]{3}/, "&'", n) sub(/^[']/, "", n) return n } { num_str = format_num($1) printf "%*s : %s\n", 11, num_str, $2 } ' done < "$input"
验证结果
修改后,带千位分隔符的数字会正确右对齐,和预期结果一致:
155 283 : / 0 : /100_samba 462 : /backup_sys 62 : /backup_sys_data 0 : /bdd 0 : /data 0 : /data1_pub 1 : /data3_dwnld_pub 0 : /data4_mk_dvd_pub 0 : /data5_my_tmp_pub 1 211 : /home 0 : /local 13 : /root 0 : /srv 33 313 : /virtual_0_backup_vdi 14 689 : /virtual_linux_1 99 116 : /virtual_win_1 300 : /win_linux_echange_1
内容的提问来源于stack exchange,提问作者jcdole
相关产品推荐
相关产品推荐

