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

[文本处理] [已解决]空格补位,把输出内容对齐的批处理

a.txt 内容
aa  1232   米
bbbbb  66  米
想要把内容补空格后输出到 b.txt
aa          1232    米
bbbbb     66       米
以下我测试的代码,不能达到预期效果,请各位围观帮忙,先行谢过
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "k=                    "
  4. (for /f "tokens=1-4  delims=  " %%a in (a.txt) do (
  5.     set "n1=%%a" && set "n2=%%b" && set "n3=%%c" && set "n4=%%d"
  6.     set a=!n1!%k% && set b=!n2!%k%  && set  c=!n3!%k%  && set  d=!n4!%k%
  7.     echo.  !a:~0,15! !b:~0,15! !c:~0,15! !d:~0,15!
  8. )) > b.txt
  9. endlocal
复制代码
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

嵌套变量延迟开关, 来消除文本中“!”的影响,弃用for %%i in (...) do...的方法,通吃文本中存在默认分隔符以及*?通配符等字符的影响,使用大多数人熟悉的cmd命令书写代码。感觉效率还可以:
  1. @echo off
  2. echo,>$1
  3. :a
  4. set Em=
  5. set /a colsn+=1
  6. if %colsn% equ 1 (
  7.     (for /f "tokens=1" %%i in (a.txt) do (echo,%%i&set Em=1))>temp
  8. ) else (
  9.     (for /f "tokens=1,%colsn%" %%i in (a.txt) do (echo,%%j&if not "%%j"=="" set Em=1))>temp
  10. )
  11. if not defined Em goto :b
  12. echo,>>temp
  13. findstr /n /o .* temp>$2
  14. setlocal enabledelayedexpansion
  15.     for /f "tokens=1,2 delims=:" %%i in ($2) do (
  16.         set /a m=%%j-x
  17.         set /a n=%%i-1
  18.         set "a!n!=!m!"
  19.         if !max! lss !m! set "max=!m!"
  20.         set "x=%%j"
  21.     )
  22. set /a n+=1
  23.     (for /f "delims=:" %%i in ('findstr /n .* temp') do (
  24.         set str1=
  25.         set str2=
  26.         set /p str1=
  27.         set /a z=max-a%%i
  28.         for /l %%k in (1,1,!z!) do set str2=!str2!
  29.         if %%i neq !n! echo,!str1!!str2!
  30.     ))<temp>$2
  31.     (for /f "tokens=1* delims=:" %%i in ('findstr /n .* $2') do (
  32.         endlocal
  33.         set /p Line1=
  34.         set Line2=%%j
  35.         setlocal enabledelayedexpansion
  36.         if "!Line1!"=="" (echo,!Line2!) else echo,!Line1!    !Line2!
  37.     ))<$1>b.txt
  38. type b.txt>$1
  39. endlocal
  40. if defined Em goto :a
  41. :b
  42. del temp $1 $2
  43. pause
复制代码

TOP

算字节长度其实也可以将文本转换为16进制字串进行计算和处理,而且不用担心任何特殊字符。
  1. @echo off&setlocal enabledelayedexpansion
  2. set "input=a.txt"&set /a m=line=1&set "act=set/p=,&set/a m=1"
  3. for %%i in ("%input%") do fsutil file creATenew "%input%.zero" %%~zi >nul
  4. (for /f "tokens=2" %%a in ('fc /b "%input%" "%input%.zero"^|findstr /irc:"[0-9A-F]*: [0-9A-F][0-9A-F] 00"') do (
  5.     if /i "%%a"=="0A" (echo,&set/a m=1,line+=1,col=0) else if /i "%%a"=="0D" (echo,
  6.         for %%l in (!line!) do for /l %%i in (1,1,!col!) do (
  7.             if !C%%i_%%l! gtr !C%%imax! set/a C%%imax=C%%i_%%l
  8.             set "C%%i_%%l="
  9.             ) ) else if /i "%%a"=="20" (%act%) else if /i "%%a"=="09" (%act%) else (
  10.                     set/p=%%a
  11.                     set /a col+=m,m=0
  12.                     set /a C!col!_!line!+=1
  13.                    )
  14.         ))<nul >"%input%.temp"
  15. (for /f "delims=" %%a in (%input%.temp) do (
  16.     set /a col=0
  17.     for %%i in (%%a) do (
  18.         set /a col+=1&set "space="
  19.         set /a size=C!col!max,len=size*2+2
  20.         for /l %%i in (1,1,!size!) do set "space=!space!20"
  21.         set "outstr=%%i!space!"
  22.         for %%i in (!len!) do echo,!outstr:~0,%%i!
  23.         )   
  24.     set /p =0d0a
  25. )   )<nul >"out_%input%"
  26. del /q "%input%.zero" "%input%.temp"
  27. certutil -decodehex -f "out_%input%" "out_%input%" >nul
  28. pause
复制代码
1

评分人数

TOP

本帖最后由 qixiaobin0715 于 2024-7-23 15:54 编辑

回复 59# ppll2030
1.排版美不美观个人看法不一,只要达到各列上下对齐的效果,调整列的宽度就是小kiss,增加或减少几个空格而已;
2.如果列数都懒得搞清楚,就太那个了吧。实际上要解决这个问题也不复杂,就是在原有代码外层加上goto循环,再if几下即可。个人感觉goto语句太过难看,很少使用此循环。

TOP

本帖最后由 77七 于 2024-7-23 15:52 编辑

回复 57# ppll2030


   
去掉就行,提供两种方法...
  1. @echo off
  2. set "str=    1  2 3 *  ?    "
  3. set "str=x %str%"
  4. set "str=%str: =&echo;%"
  5. for /f "skip=1" %%a in ('echo %%str%%') do (
  6. echo [%%a]
  7. )
  8. pause
  9. for /f "tokens=*" %%a in ("    1  2 3 *  ?    ") do (
  10. set str=%%a
  11. if defined str (
  12. call set "str=%%str: =&echo;%%"
  13. for /f %%a in ('call echo %%str%%') do (
  14. echo [%%a]
  15. )
  16. )
  17. )
  18. pause
复制代码
bat小白,请多指教!谢谢!

TOP

本帖最后由 aloha20200628 于 2024-7-23 14:37 编辑

回复 60# ppll2030

我说的过滤掉中英文空格+制表符构成的 ‘全空白行’,其中的中文空格即全角空格。delims表达式指定的这三个字符复制到代码区中有时会 ‘变形’ 不过知道此意你在自己的代码中调整就是了

TOP

回复 58# aloha20200628


    老大。你的delims那边的有点问题,害我找了好久。
就是那个中英文空格你给打了三个。直接卡当了。修改为一个制表符和一个空格就OK了
像我这边,还加入全角符的空格,也完美支持了。标点符号也完美显示。
大赞哦~!

TOP

回复 56# qixiaobin0715


    你的代码有些还看不明,需要研究一下
不过31楼的大佬,貌似也是按列来取值,然后根据每列最大字符串得到每列最大宽度。从而使得结果排版更加的完美。
而它第一段可以自动识别最大的列数。不需要手动填写,或许可以借鉴到你的代码里。
他的代码后半段很复杂。我一时半会不能理解透。
等研究透aloha的版本,再去研究31楼的。毕竟aloha的版本感觉思路跟我的有相似之处,好理解一些。

TOP

本帖最后由 aloha20200628 于 2024-7-23 11:18 编辑

回复 54# ppll2030

更新了50楼代码,滤掉了全空白字符行(仅包含中英文空格+制表符),以免运行中被阻塞...

TOP

回复 55# 77七


    哈哈。果然有取巧的办法。感谢指导

不过这个用在这里会引发另一个bug

当每行开头是几个空格开始的情况,取值第一个会是ECHO

TOP

本帖最后由 qixiaobin0715 于 2024-7-24 09:40 编辑

回复 53# ppll2030
字符串分行显示时,不使用for %%a in (...) do...这样的循环结构,可以避免出现默认分隔符以及*?通配符的影响;
至于变量延迟中!会”隐藏“的问题有多种解决方法,其中一种方法可以参考http://www.bathome.net/thread-11193-1-1.html

TOP

回复 53# ppll2030


   50楼大佬已经给出答案了。如果没有其它特殊字符,只有通配符,也可以试试以下思路(老帖子看到的),将行变成竖排
  1. @echo off
  2. set "str=1  2 3 *  ?    "
  3. set "str=%str: =&echo;%"
  4. for /f %%a in ('echo %%str%%') do (
  5. echo [%%a]
  6. )
  7. pause
复制代码
bat小白,请多指教!谢谢!

TOP

回复 50# aloha20200628


    厉害了。换一个思路就搞定了特殊符号问题。这思维真是服了。

不过又有一个新问题: 对于包含有空格或制表符的空行(整行都不显示字符的,看着就像一空行),脚本会卡住,无法进行下去。

不过这不是很大的问题。我目前是加一段去除所有空行的命令,再继续执行就完美了。

再次感谢老大,通过这几段,学习到了很多。

TOP

回复 51# 77七
回复 48# qixiaobin0715

感谢两位大佬的指点。原因是已经找到了。只是想知道有没有什么好的经验或是取巧的办法可以避免这些通配符。
毕竟还想保持这么精简而干练的代码

TOP

本帖最后由 qixiaobin0715 于 2024-7-22 17:02 编辑

自己又偷偷的写了一个代码,对for默认分隔符和通配符 *?以及延迟变量中的 ! 免疫,效率不行,没好意思发出来。

TOP

返回列表