下面的代码应该在第 1 列中留下填充编号。
\ninput="/home/user_install/folders_LIST_SIZES_MY_FOLDERS.txt"\nwhile IFS= read -r line ; do \n sudo du -sm $line | LC_NUMERIC=fr_FR.UTF8 awk '{printf "% 11 '\\''d : %s\\n", $1 , $2}'\ndone < "$input"\n\nRun Code Online (Sandbox Code Playgroud)\n预期结果应该是:
\n 155\xe2\x80\xaf283 : /\n 0 : /100_samba\n 462 : /backup_sys\n 62 : /backup_sys_data\n 0 : /bdd\n 0 : /data\n 0 : /data1_pub\n 1 : /data3_dwnld_pub\n 0 : /data4_mk_dvd_pub\n 0 : /data5_my_tmp_pub\n 1\xe2\x80\xaf211 : /home\n 0 : /local\n 13 : /root\n 0 : /srv\n 33\xe2\x80\xaf313 : /virtual_0_backup_vdi\n 14\xe2\x80\xaf689 : /virtual_linux_1\n 99\xe2\x80\xaf116 : /virtual_win_1\n 300 : /win_linux_echange_1\n\nRun Code Online (Sandbox Code Playgroud)\n真正的结果是:
\n 155\xe2\x80\xaf283 : /\n 0 : /100_samba\n 462 : /backup_sys\n 62 : /backup_sys_data\n 0 : /bdd\n 0 : /data\n 0 : /data1_pub\n 1 : /data3_dwnld_pub\n 0 : /data4_mk_dvd_pub\n 0 : /data5_my_tmp_pub\n 1\xe2\x80\xaf211 : /home\n 0 : /local\n 13 : /root\n 0 : /srv\n 33\xe2\x80\xaf313 : /virtual_0_backup_vdi\n 14\xe2\x80\xaf689 : /virtual_linux_1\n 99\xe2\x80\xaf116 : /virtual_win_1\n 300 : /win_linux_echange_1\nRun Code Online (Sandbox Code Playgroud)\n当数字超过 3 位时,左移 1 位。
\n使用输入数字1234567,123456和123...
如果我使用LC_NUMERIC=en_US逗号作为千位分隔符来正确排列所有内容
1,234,567 :\n 123,456 :\n 123 :\nRun Code Online (Sandbox Code Playgroud)\n如果我使用LC_NUMERIC=fr_FR.UTF8我会得到与OP输出中看到的相同的转变
1\xc2\xa0234\xc2\xa0567 :\n 123\xc2\xa0456 :\n 123 :\nRun Code Online (Sandbox Code Playgroud)\n对于第二组数据,就好像空格分隔符后面跟着一个退格键,或者也许......由多字节字符表示?
\n将第二组数据通过管道传输到od -c我得到:
0000000 1 302 240 2 3 4 302 240 5 6 7 : \\n\n0000020 1 2 3 302 240 4 5 6 : \\n\n0000040 1 2 3 : \\n\n0000052\nRun Code Online (Sandbox Code Playgroud)\n因此,该 1 字节空格分隔符实际上被实现为 2 个字节(302 240- 一个可打印字符,一个不可打印字符)。
由于printf格式设置基于字节数而不是(可打印)字符数,因此每个不可打印字符“占用”一个输出位置,从而导致最终输出移动(或缩小)一个(可见/可打印)位置。
一种解决方法是将格式化分为两个单独的操作,例如:
\nprintf '1234567\\n123456\\n123\\n' |\nLC_NUMERIC=fr_FR.UTF8 awk '{ x = sprintf("%\\04711d",$1 ) # format just the number\n printf "%13s :\\n",x # feed formatted number to basic string format\n }'\nRun Code Online (Sandbox Code Playgroud)\n这会生成:
\n 1\xc2\xa0234\xc2\xa0567 :\n 123\xc2\xa0456 :\n 123 :\nRun Code Online (Sandbox Code Playgroud)\n注意: 2个字节仍然存在,即通过管道传输这组最新的数据来od -c生成
0000000 1 302 240 2 3 4 302 240 5 6 7\n0000020 : \\n 1 2 3 302 240 4 5 6\n0000040 : \\n 1 2 3\n0000060 : \\n\n0000063\nRun Code Online (Sandbox Code Playgroud)\n一些注意事项:
\n如果 OP 期望处理 11 位数字,则(s)printf可能需要修改格式11d/13s
正如评论部分(KamilCuk、Ed Morton、我)中突出显示的那样,构成“空格分隔符”的实际字节甚至字节数(2 字节与 3 字节)可能会根据所用版本的不同而有所glibc不同建立fr_FR.UTF-8语言环境;对于 3 字节字符,这将导致每个分隔符将输出吃掉/移动 2 个(打印)字符;awk设计用于处理字符而不是字节,因此任何动态确定构成 1000 分隔符的字节数的尝试都需要额外的工作(例如:调用system(); 进行wc预计算bash,然后作为-v awk_var=byte_count参数传递给awk; awk -b)