[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
本帖最后由 newswan 于 2024-7-19 00:22 编辑

假如知道最大宽度是10
  1. awk '{ printf "%-10s %-10s %-10s\n", $1, $2, $3 }' a.txt
复制代码

TOP

回复 12# 娜美
只要计算出每列的最大字节数,以及各列字节数与最大字节数的差值,然后用空格补齐即可。
可能会稍微复杂些,抽空试试。
1

评分人数

TOP

回复 17# qixiaobin0715


    请问大佬,有没有办法输出到txt还能保持队形的。
上面的大佬们都是cmd下输出结果。
计算最大字符串并补齐空格,这个我也搞出来了。
就是不能输出到txt还保持不变形。

TOP

本帖最后由 qixiaobin0715 于 2024-7-19 12:47 编辑

回复 18# ppll2030
输出的txt文件你用“记事本”打开看看。
不同的文本编辑器,字符不同占用宽度可能会有区别。

TOP

回复 19# qixiaobin0715


    显示宽度其实是取决于字体,等宽还是比例,全角和半角等,控制台一般是consoles字体,是等宽的,全角输入中英文字符也是相同宽度。

TOP

回复 19# qixiaobin0715


    感谢指导。看来是字体问题了。
换了自带记事本,依然混乱。

TOP

回复 20# buyiyang


    感谢解惑。更换字体后txt文件得到对齐的结果了。

TOP

本帖最后由 newswan 于 2024-7-19 14:32 编辑

1 字体的宽度,夹杂中文,更纱一个字体,能完全对齐
2 中文的宽度,上面的所有方案,都没有计算中文宽度,用制表符处理误差,一旦前面中文过多,也不能对齐。

TOP

本帖最后由 qixiaobin0715 于 2024-7-19 14:54 编辑

按照各列字节数与最大字节数的差值,然后用空格补齐的方法,适用含有中文字符的列:
  1. @echo off
  2. set colsn=4
  3. set /a colsn-=1
  4. for /f "tokens=1-%colsn%" %%1 in (a.txt) do (
  5.     echo,%%1>>temp1
  6.     echo,%%2>>temp2
  7.     echo,%%3>>temp3
  8. )
  9. setlocal enabledelayedexpansion
  10. for /l %%a in (1,1,%colsn%) do (
  11.     echo,a>>temp%%a
  12.     set /a x=n%%a=0
  13.     for /f "tokens=1,2 delims=:" %%i in ('findstr /n /o .* temp%%a') do (
  14.         set /a "x%%a=%%j-x"
  15.         set /a "m=%%i-1"
  16.         set "n%%a#!m!=!x%%a!"
  17.         if !n%%a! lss !x%%a! set /a "n%%a=x%%a"
  18.         set "x=%%j"
  19.     )
  20.     del temp%%a
  21. )
  22. for /f "tokens=1-%colsn%*" %%1 in (a.txt) do (
  23.     set /a "n+=1"
  24.     set f=
  25.     set "f1=%%1"
  26.     set "f2=%%2"
  27.     set "f3=%%3"
  28.     for /l %%x in (1,1,%colsn%) do (
  29.         set /a "m%%x=n%%x-n%%x#!n!"
  30.         for /l %%y in (1,1,!m%%x!) do set "f%%x=!f%%x! "
  31.         set "f=!f!!f%%x!    "
  32.     )
  33.     echo,!f!%%4
  34. )
  35. pause
复制代码
由于未及仔细考虑,代码存在以下缺点:
1.代码过于复杂,可读性差;
2.除最后一列外,其余各行各列字节数均预先设置变量,处理较大文件时,速度可能会比较慢,甚至超出变量设置的上限而出错;
3.上面代码是按4列文本来处理的,如果列数有变化,需要对以上代码进行修改(虽然写代码时,考虑到了列数变化时,尽量减少修改量),通用性不是太好。

下面举例说明列数变化时,代码调整的方法:
1.如果文本内容的列数为3列,代码做如下调整:
第2行变量值修改为3;
删除第7行;
删除第27行;
将第33行的%%4改为%%3;
2.如果文本内容的列数为5列,代码做如下调整:
第2行变量值修改为5;
第7行下面增加一行:echo,%%4>>temp4
第27行下面增加一行:set "f4=%%4"
将第33行的%%4改为%%5;

TOP

我也发一个吧。也是用字节数补齐空格的方式。
就是代码啰嗦了一些。而且局限列数为5列。
不知道还能不能精简,望各位老大指点一二。
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. rem 计算字符的字节,cmd下输出是对齐状态,导出txt会变形,需改换等宽字体,cmd默认是Consolas。
  4. REM 获取文本最大字符串的字节
  5. for /f "delims=" %%a in (1.txt) do for %%s in (%%a) do (
  6. set/p="%%s"<nul>$
  7. for %%b in ($) do if %%~zb gtr !maxZ! set "maxZ=%%~zb"
  8. )
  9. for /f "tokens=1-4*  delims= " %%a in (1.txt) do (
  10.     rem 获取每列字符串的字节
  11.     set "a=%%a"&set "b=%%b"&set "c=%%c"&set "d=%%d"&set "e=%%e"
  12.     set/p="%%a"<nul>$&for %%i in ($) do (set az=%%~zi)
  13.     set/p="%%b"<nul>$&for %%i in ($) do (set bz=%%~zi)
  14.     set/p="%%c"<nul>$&for %%i in ($) do (set cz=%%~zi)
  15.     set/p="%%d"<nul>$&for %%i in ($) do (set dz=%%~zi)
  16.     set/p="%%e"<nul>$&for %%i in ($) do (set ez=%%~zi)
  17.     rem 获取每列字符串的字节差,并用空格补齐
  18.     set/a Na=!maxZ!-!az!&set/a Nb=!maxZ!-!bz!&set/a Nc=!maxZ!-!cz!&set/a Nd=!maxZ!-!dz!&set/a Ne=!maxZ!-!ez!
  19.     for /l %%i in (1,1,!Na!) do set "a=!a! "
  20.     for /l %%i in (1,1,!Nb!) do set "b=!b! "
  21.     for /l %%i in (1,1,!Nc!) do set "c=!c! "
  22.     for /l %%i in (1,1,!Nd!) do set  "d=!d! "
  23.     rem for /l %%i in (1,1,!Ne!) do set  "e=!e! "
  24.     echo !a! !b! !c! !d! !e!
  25. )
  26. del/q $&pause&exit
复制代码

TOP

本帖最后由 newswan 于 2024-7-20 01:54 编辑

保存为 a.awk ,然后 awk -f a.awk a.txt
  1. BEGIN {
  2. FS = " "
  3. while ( getline < ARGV[1] ) {
  4. for (i = 1; i <= NF; i++) {
  5. if ( length($i) > maxlen[i] ) {
  6. maxlen[i] = length($i)
  7. }
  8. }
  9. }
  10. }
  11. {
  12. for (i = 1; i <= NF; i++) {
  13. printf "%-*s\t",maxlen[i],$i
  14. }
  15. printf "\r\n"
  16. }
复制代码
1

评分人数

TOP

不如将空格换成tab
文本编辑器来打开时会自行处理

TOP

powershell
  1. $file = Get-Content -Path "data.txt" -Encoding UTF8
  2. $maxlen = @(0) *10
  3. $file | ForEach-Object {
  4. $arr = $_  -split "\s+"
  5. for ( $i =0 ; $i -lt $arr.count ; $i++ ){
  6. if ( $maxlen[$i] -lt ($arr[$i]).length ) {
  7. $maxlen[$i] = ($arr[$i]).length
  8. }
  9. }
  10. }
  11. $maxlen = $maxlen -join " " -replace "( 0)*" -split "\s+"
  12. $file | ForEach-Object {
  13. $arr = $_  -split "\s+"
  14. $str = ""
  15. for ( $i =0 ; $i -lt $arr.count ; $i++ ){
  16. $str += ($arr[$i]).PadRight($maxlen[$i]," ") + "  "
  17. }
  18. write-host ( $str -replace "\s$","" )
  19. }
复制代码

TOP

本帖最后由 娜美 于 2024-7-20 13:58 编辑

回复 26# newswan

长度如果不超过宽度基本没有问题

   但如遇到这样的长短都不一
  1. aa          1232    米
  2. bbbbb     66       米
  3. b 66  米
  4. cccccccccccccccccccccccccccccccccccc    c   cccccccccccccccccccccccccccccc  cc   c          米 c
  5. c cc    ccc     v          米
  6. 补补补补补补补补补补补补补补补补补  cccccccccccccccccccccccccccccc          补补补补补补补补补补补补补补补补补       c       c                 c
  7. 补  c                      cccccccccccccccccccccccccccccc    c             c                c
复制代码
想要完全解决问题,  似乎需要检查每1列最后一个空格在什么位置, 记录后一个空格位置数值,  再用空格来填充所有,   才可以彻底解决

TOP

回复 20# buyiyang

批处理没有格式化输出,要对齐要注意两点:
    1.等宽字体和比例字体。等宽字体每个西文宽度相同,才能对齐;而比例字体会将西文宽度按比例调整以便于观看。中文一般都是等宽的。
    2.全角和半角。半角字符占1个标准字符宽度,西文(包括空格)一般为半角;而全角字符占2个标准字符宽度,中文均为全角。
楼上批处理是根据字节计算宽度的,有findstr算偏移量、for的%%~zi增强扩展算size的,都是根据:
    在ansi(gb2312)编码中一个汉字必须是两个值大于127的字节连在一起,并兼容ASCII。所以一个汉字=2个字节=2个标准字符宽度,一个ASCII字符=1个字节=1个标准字符宽度。
其实可以通过if比较区分每个字符是中文还是英文。
还有通过控制台437代码页将双字节的字符分成两个字符来算字符宽度的方法。
如果是utf-8等其他编码方式则会不同。

TOP

返回列表