标题: 【练习-003】批处理实现文本左右对齐排版 [打印本页]
作者: pusofalse 时间: 2008-7-25 21:11 标题: 【练习-003】批处理实现文本左右对齐排版
如1.txt内容如下。- 111111111111111111111 98912 张三
- 222222222222222222 150020 李四四
- 333333333333333333333 360000 王五
- 444444444444444444 2332 赵六六
- 555555555555555555 222 田七
- 666666666666666666666 999999 舞吧
复制代码
通过批处理输出为:-
- 111111111111111111111 98912 张三
- 222222222222222222 150020 李四四
- 333333333333333333333 360000 王五
- 444444444444444444 2332 赵六六
- 555555555555555555 222 田七
- 666666666666666666666 999999 舞吧
复制代码
代码要求,不生成任何临时文件。
代码简洁,视思路与代码加分!
------------------------------------------------------------------------------------------
本题只是给出一个简单的文本通过批处理排版,而要求代码的通用,正如batman版主所说,会是一个繁琐的过程,于是就题解题,不必考虑代码的通用。
[ 本帖最后由 batman 于 2008-7-27 23:57 编辑 ]
作者: batman 时间: 2008-7-25 22:48
我来帮大家理思路吧:
所有的列其实都是左右对齐,大家想下为什么吧。
[ 本帖最后由 batman 于 2008-7-26 01:25 编辑 ]
作者: 浅默 时间: 2008-7-26 06:55
@echo off
Setlocal Enabledelayedexpansion
set n=0
for /f "tokens=1,2*" %%i in (1.txt) do (
set "ke=%%i %%j"
set m=0
call :1
)
for /f "tokens=1,2*" %%i in (1.txt) do (
set "ke1=%%i %%j"
set ke2=%%i
set m1=0
call :2
echo !ke2! %%j %%k
)
pause
goto :eof
:1
if not "!ke:~%m%,1!"=="" set /a m+=1&goto 1
if %m% gtr %n% set n=%m%
goto :eof
:2
if not "!ke1:~%m1%,1!"=="" set /a m1+=1&goto 2
set /a dd=n-m1
for /l %%a in (1,1,%dd%) do set "ke2=!ke2! "
goto :eof
作者: fastslz 时间: 2008-7-26 11:31
不知道大家发现没?其实cmd文本排版是有潜规则的!
作者: youxi01 时间: 2008-7-26 12:08
呵呵,是
作者: pusofalse 时间: 2008-7-26 16:46
是。^_^
作者: pusofalse 时间: 2008-7-26 17:36
我本人的解,还是很繁琐,思路跟浅默的差不多。望更多人参与此题,求得更多的解!
-
- @echo off&setlocal enabledelayedexpansion
- set length=0
- for /f "tokens=1,2" %%a in (1.txt) do (
- set x=0
- call :lp %%a%%b
- if !x! gtr !length! set length=!x!
- )
- set/a length+=4
- for /f "tokens=1,2,*" %%a in (1.txt) do (
- set x=0
- set/p=%%a <nul
- call :lp %%a%%b
- set/a s=length-x
- for /l %%i in (1 1 !s!) do set/p= <nul
- set/p=%%b<nul
- set/p= %%c<nul
- echo.
- )
- pause&exit/b
- :lp
- set str=%1
- :lp1
- if defined str set str=!str:~1!&set/a x+=1&goto lp1
复制代码
作者: fastslz 时间: 2008-7-26 18:11
这个是潜规则默认排版方式- @echo off
- for /f "delims=*" %%a in (1.txt) do call :xxx %%a
- pause&exit
-
- :xxx
- set "str=%*"
- REM 注意:等号左侧是制表符
- set "str=%str: = %"
- echo.%str%
- goto:eof
复制代码
作者: pusofalse 时间: 2008-7-26 18:22
原帖由 fastslz 于 2008-7-26 18:11 发表
这个是潜规则默认排版方式
@echo off
for /f "delims=*" %%a in (1.txt) do call :xxx %%a
pause&exit
:xxx
set "str=%*"
set "str=%str: = %"
echo.%str%
goto:eof
第一次看到如此的方法,还没弄明白怎么回事,在我电脑上测试着不正确。但仍旧学习了!~
作者: fastslz 时间: 2008-7-26 18:35
是论坛字符问题
方法其实很简单call标签删除前面及后面的空格字符,替换空格字符为Tab键字符set "str=%str: =这里是Tab键字符%"
附上附件
作者: pusofalse 时间: 2008-7-26 18:42
原帖由 fastslz 于 2008-7-26 18:35 发表
是论坛字符问题
方法其实很简单call标签删除前面及后面的空格字符,替换空格字符为Tab键字符set "str=%str: =这里是Tab键字符%"
附上附件
测试文本:
- 1111111 aaaaaaaaaaaa 张三
- 222222sdf222222222222 150020 李四四
- 3333333sfd33333333333333 0 王五
- 44444444444aa4444444 2332 赵sdfafa六六
- 555555555 222 田七
- 666666666666666666666asaaaaaaaaa 9999999999999 舞
复制代码
作者: batman 时间: 2008-7-26 18:47 标题: 就题解题
个人认为如本题要充分考虑代码通用性的话,就会是一个相当复杂的过程,
于是,就题解题:- @echo off&setlocal enabledelayedexpansion
- set "kong= "
- for /f "delims=" %%a in (1.txt) do (
- for %%i in (%%a) do (
- set "str=%%i"&set /a n+=1
- if !n! equ 2 (
- set "str=%kong%!str!"
- set /p=!str:~-10! <nul
- ) else (
- set "str=!str!%kong%"
- set /p=!str:~,20! <nul
- ))
- set "n=0"&echo.
- )
- pause>nul
复制代码
作者: batman 时间: 2008-7-26 19:04
原帖由 fastslz 于 2008-7-26 18:35 发表
是论坛字符问题
方法其实很简单call标签删除前面及后面的空格字符,替换空格字符为Tab键字符set "str=%str: =这里是Tab键字符%"
附上附件
使用制表符是默认的左对齐分列,主要用来从文本向excel中导数据。
作者: 风行者 时间: 2008-7-26 20:03 标题: 我是最最新手,向你们学习
- @echo off & setlocal enabledelayedexpansion
- for /f "tokens=1-3 delims= " %%a in (1.txt) do (
- set /a n+=1
- if !n!==1 echo %%a %%b %%c
- if !n!==2 echo %%a %%b %%c
- if !n!==3 echo %%a %%b %%c
- if !n!==4 echo %%a %%b %%c
- if !n!==5 echo %%a %%b %%c
- if !n!==6 echo %%a %%b %%c
- )
- pause
复制代码
作者: pusofalse 时间: 2008-7-26 20:08
可以直接这样。。
echo 111111111111111111111 98912 张三
echo 222222222222222222 150020 李四四
echo 333333333333333333333 360000 王五
...
...
加分鼓励!一同进步!
作者: batman 时间: 2008-7-26 20:17
原帖由 风行者 于 2008-7-26 20:03 发表
@echo off & setlocal enabledelayedexpansion
for /f "tokens=1-3 delims= " %%a in (1.txt) do (
set /a n+=1
if !n!==1 echo %%a %%b %%c
if !n!==2 echo %%a %%b %%c
if !n!==3 echo %%a ...
这种解法的确是太可爱了,100%的就题解题!
作者: 浅默 时间: 2008-7-26 20:29
使用tab键的都有哪些条件呢?11楼的测试文件不能成功,如果两行差距太大也不成功.
作者: namejm 时间: 2008-7-26 20:36
默认情况下,一个tab键产生的空格相当于8个空格键产生的空格,如果字符串少于8个字符,则一个tab键就足够排版;如果多于8个字符,那么,一个tab键就没法排版了,需要增加tab键的个数,以保证tab键产生的空格个数多于字符串长度。
作者: more 时间: 2008-7-27 14:51
- @echo off
- setlocal enabledelayedexpansion
- for /f "tokens=1,2*" %%a in ('type temp.txt') do (
- set "mo=%%a"&set "niu=%%b"&set "m=0"&set "n=0"&set "very="
- call :ming0 %%a %%b %%c
- )
- echo.&pause&exit
- :ming0
- if not "!mo:~%m%,1!"=="" (set "momo=!mo:~%m%,1!"&set /a "m+=1"&goto :ming0)
- :ming1
- if not "!niu:~%n%,1!"=="" (set "niuniu=!niu:~%n%,1!"&set /a "n+=1"&goto :ming1)
- set /a "ming=30-%m%-%n%"
- for /l %%i in (1 1 %ming%) do set "very=!very! "
- echo %1 %very% %2 %3
复制代码
作者: 523066680 时间: 2008-8-12 11:17 标题: 我也行!
- @echo off
- setlocal enabledelayedexpansion
- set a=0
- for /f "eol= tokens=1,2,3" %%a in ('type 1.txt') do (
- set /a a+=1
- set "lie1=%%a "
- set lie1=!lie1:~0,30!
- set "lie2=%%b "
- set lie2=!lie2:~0,20!
- echo,!lie1!!lie2:%%b=!%%b %%c
- )
- pause
复制代码
作者: 523066680 时间: 2008-8-12 14:13
我稍微换一下思路,应该说是尽量的通用了……如果某文本太过畸形 那也是没办法的事了……
文本内容更新为:- 111111111111111111111 98912 张三
- 222222222222222222 150020 李四四
- 333333333333333333333 360000 王五
- 4444444444444444444321542365445432453243243423432 11111143242342332 赵六六
- 555555555555555555 222 田七
- 666666666666666666666 999999 舞吧
复制代码
- @echo off
- mode con cols=100 lines=20
- setlocal enabledelayedexpansion
- for /l %%a in (1,1,80) do set kong= !kong!
- for /f "eol= tokens=1,2,3" %%a in ('type 1.txt') do (
- set lie1-2=%%a%%b%kong%
- set lie1-2=!lie1-2:~0,80!
- set lie1-2=%%a!lie1-2:%%a%%b=!%%b
- echo,!lie1-2! %%c
- )
- pause
复制代码
原理:例如文本内容为:
ab******1*d
abc*************2********e
用for获得前面的两列
直接组合 则免去了中间的空格:
ab1
abc2
直接加上80个空格
ab1***************************……
abc2***************************……
然后保存前80位。
ab1*********……***
abc2********……***
把空格前移
ab*********……***1
abc********……***2
这样前面的就基本对齐了。后面的第三列 就不用说了…
我觉得应该可以了……至少我自己用不上太通用的,这个代码自己也没有当工具用过
忽忽……加了中文 或者字符……就被淘汰了……
[ 本帖最后由 523066680 于 2008-8-12 15:49 编辑 ]
作者: terse 时间: 2008-8-12 18:37
我来个 补齐字符方法 效率不怎么样- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=*" %%i in (1.txt) do call :lp %%i
- for /l %%i in (1 1 %t%) do for /l %%j in (1 1 !%%il!) do set "%%iv=!%%iv! "
- for /f "tokens=*" %%i in (1.txt) do call :lp0 %%i
- pause&exit
- :lp0
- set/a n+=1
- if "%1"=="" set n=& echo %str1%&set str1=&goto :eof
- set "str=%1!%n%v!"
- call set "str1=%str1%%%str:~,!%n%l!%%"
- shift
- goto lp0
- :lp
- set/a n+=1
- if not defined %n%l set %n%l=0
- if "%1"=="" set n=&goto :eof
- for /f "skip=1 delims=:" %%i in ('^(echo %1^&echo.^)^|findstr /o ".*"') do set m=%%i
- set t=%n%
- if %m% gtr !%n%l! set %n%l=%m%
- shift
- goto lp
复制代码
作者: 随风 时间: 2008-8-12 21:27
不知此帖是否够通用?不过创建了临时文件。
http://bbs.bathome.net/viewthrea ... mp;highlight=%C5%C5
作者: weichenxiehou 时间: 2010-12-30 22:11
新接触批处理,很有意思,请各位大侠多多指教。在此送上我的代码,多多指教!既然各位大侠都说了就题解题,那不好意思了,嘿嘿……
- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=1-3" %%i in (test.txt) do (
- set temp1=%%i$$$$$&set temp2=$$$$$%%j&set temp3=%%k$$$$$
- set temp1=!temp1:~0,21!&set temp2=!temp2:~-6!&set temp3=!temp3:~0,3!
- set tempstr=!temp1! !temp2! !temp3!
- set tempstr=!tempstr:$= !
- echo !tempstr!
- )
复制代码
[ 本帖最后由 weichenxiehou 于 2010-12-30 23:37 编辑 ]
作者: vincentzhou 时间: 2011-1-9 15:01
- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=1-3" %%a in (1.txt) do (
- set str=%%a%%b
- call:count
- set a=%%a
- set /a num=32-!num!
- set/p=!a!<nul
- for /l %%i in (1 1 !num!) do (set /p= <nul)
- echo %%b %%c
- )
- pause>nul
- :count
- if defined num set num=
- :loop
- if not "!str!"=="" (
- set str=!str:~1!
- set /a num+=1
- goto loop
- )
复制代码
作者: CrLf 时间: 2011-2-22 18:46
下载了10楼附件,可是还是没效果啊,莫非win7不支持这样么...
作者: shelluserwlb 时间: 2014-12-17 23:41
- @echo off
- setlocal EnableDelayedExpansion
- set "space= "
- for /f "tokens=1,2*" %%a in (1.txt) do (
- set "str1=%%a"& set /a n=0
- set /a s=1 & call :1
- set "x=!str1!!str2!" & set str2=
-
- set "str1=%%b" & set /a n=0
- set /a s=2 & call :1
- set "y=!str2!!str1!" & set str2=
-
- set "str1=%%c" & set /a n=0
- set /a s=3 & call :1
- set "z=!str2!!str1!" & set str2=
- echo !x!!y!!z!
- )
- pause>nul
- goto :eof
- :1
- if not "!str1:~%n%,1!"=="" set /a n+=1 & goto :1
- if %s% equ 1 (set /a m=26-%n% & goto :2)
- if %s% equ 2 (set /a m=10-%n% & goto :2)
- set /a m=10
- :2
- for /l %%i in (1,1,!m!) do set "str2=!str2!%space%"
- goto :eof
复制代码
效果见下图:
作者: bailong360 时间: 2015-3-15 09:04
- @Echo Off
- SetLocal EnableDelayedExpansion
- For /F "Tokens=1,2,3" %%i In (1.txt) Do (
- Set L1=%%i
- Set L2= %%j
- Echo !L1:~0,25!!L2:~-15! %%k
- )
复制代码
作者: 尘丶 时间: 2015-9-18 17:51
- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=1,2,3 delims= " %%a in (a.txt) do (
- set k=%%a
- set k1=%%b
- for /l %%c in (1,1,25) do if "!k:~%%c,1!"=="" set "k=!k! "
- for /l %%d in (1,1,5) do if "!k1:~%%d,1!"=="" set "k1=!k1! "
- echo;!k! !k1! %%c
- )
- pause
复制代码
作者: 依山居 时间: 2015-11-4 12:38
- # python版实现文本左右对齐排版
- # 题目来源: http://www.bathome.net/thread-1246-1-1.html
- # 依山居 7:17 2015/11/4
-
- # str.format 字符串格式化参考:
- # http://www.crifan.com/python_string_format_fill_with_chars_and_set_alignment/
-
- # just()字符串对齐 参考:
- # http://blog.csdn.net/u012515223/article/details/20463231
- '''
- 1.txt内容:
- 111111111111111111111 98912 张三
- 222222222222222222 150020 李四四
- 333333333333333333333 360000 王五
- 444444444444444444 2332 赵六六
- 555555555555555555 222 田七
- 666666666666666666666 999999 舞吧
- '''
-
- #说明我的代码没按题目要求全部使用空格填充是为了让代码用法看起来直观一些。
-
- #方法一 format格式化对齐
- def f1():
- with open("1.txt","r") as f:
- for s in f:
- l=s.rsplit ()
- t='{0:-<25} {1: >7} {2}'.format(l[0],l[1],l[2])
- print(str(t))
-
- '''
- 输出:
- 111111111111111111111---- 98912 张三
- 222222222222222222------- 150020 李四四
- 333333333333333333333---- 360000 王五
- 444444444444444444------- 2332 赵六六
- 555555555555555555------- 222 田七
- 666666666666666666666---- 999999 舞吧
- '''
-
- #方法2 使用just()对齐
- r=''
- def f2():
- f=open("1.txt","r")
- for s in f:
- l=s.rsplit()
- print(l[0].ljust(25," "),l[1].rjust(10,"^"),l[2])
-
- '''
- 输出:
- 111111111111111111111 ^^^^^98912 张三
- 222222222222222222 ^^^^150020 李四四
- 333333333333333333333 ^^^^360000 王五
- 444444444444444444 ^^^^^^2332 赵六六
- 555555555555555555 ^^^^^^^222 田七
- 666666666666666666666 ^^^^999999 舞吧
- '''
-
- #方法3
- '''
- 思路是rsplit拆分成三列,l得到如['111111111111111111111', '98912', '张三']
- 算出列1,列2的最长,以此算出需要填充的长度,
- '''
- def f3():
- f=open("1.txt","r")
- txt=f.readlines()
- maxa=0
- maxb=0
- for line in txt:
- line=line.rsplit()
- la=len(line[0])
- lb=len(line[1])
- if la >maxa:
- maxa=la
- if lb > maxb:
- maxb=lb
-
- for line in txt:
- line=line.rsplit()
- la=len(line[0])
- lb=len(line[1])
- if la ==maxa:
- tla=line[0]
- elif la<maxa:
- tla=line[0]+">"*(maxa-la)
- if lb ==maxb:
- tlb=line[1]
- elif lb<maxb:
- tlb=" "*(maxb-lb)+line[1]
- print(tla,tlb,line[2])
- '''
- 输出:
- 111111111111111111111 98912 张三
- 222222222222222222>>> 150020 李四四
- 333333333333333333333 360000 王五
- 444444444444444444>>> 2332 赵六六
- 555555555555555555>>> 222 田七
- 666666666666666666666 999999 舞吧
- '''
复制代码
作者: 依山居 时间: 2015-11-6 01:54
- """
- #方法4 重用了方法3的上半部分代码算出列1列2最大长度,以此对齐顶点。
- #这个方法的思路是不使用空格或者其它符号填充,而是在写入文件时,
- #指针直接前移使字符对齐。空的字符位置会自动被\x00填充?
- #
- """
- def f4():
-
- f=open("1.txt","r")
- txt=f.readlines()
- maxa=0
- maxb=0
- for line in txt:
- line=line.rsplit()
- la=len(line[0])
- lb=len(line[1])
- if la >maxa:
- maxa=la
- if lb > maxb:
- maxb=lb
-
- w=open("temp.txt","w+")
- for line in txt:
- line=line.rsplit()
- la=len(line[0])
- lb=len(line[1])
- w.write(line[0])
- #算了半天
- tw=maxa+maxb+1-la-lb
- w.seek(tw+w.tell())
- w.write(line[1])
- w.seek(w.tell()+1)
- w.write(line[2]+"\n")
- w.flush()
- w.seek(0)
- txt=w.read()
- print(txt)
-
- """
- 输出:
- 111111111111111111111
复制代码
-_-!剪贴碰到00自动截断了。输出内容不能完全贴上来。
作者: ShenMian 时间: 2018-1-20 22:50
本帖最后由 ShenMian 于 2018-1-20 22:52 编辑
格式printf 字符串1 空格数 字符串2 空格数 ... 空格数 字符串n
代码:- @echo off
- setlocal enabledelayedexpansion
- for /f "tokens=1,2,3" %%a in (1.txt) do (
- call:printf %%a 20 %%b 20 %%c
- echo;
- )
- exit /b
-
- :printf
- set /p "=%~1"<nul
- set length=0
- set "str=%~1"
- :printf_0
- if "!str:~%length%!" == "" (
- for /l %%a in (%length%,1,%2) do set /p = <nul
- shift
- shift
- if not "%~3" == "" goto printf
- exit /b
- )
- set /a length+=1
- goto printf_0
复制代码
作者: yujw668 时间: 2018-8-27 17:29
回复 12# batman
版主,您好,看了您的代码很实用,但是如果有一种情况就是第二列有空的,怎么处理呢?
例如原文本:
111111111111111111111 98912 张三
222222222222222222 150020 李四四
333333333333333333333 360000 王五
444444444444444444 赵六六
555555555555555555 田七
666666666666666666666 999999 舞吧
如果第二列为空的话,生成的第三列就跑到了第二列去了,请问下怎么解决呢?
作者: ai20110304 时间: 2018-9-4 15:42
回复 1# pusofalse - ::文本两端对齐
- @echo off & setlocal enabledelayedexpansion
- cd /d %~dp0
- ::将空格替换成#号,再在基础上进行切割,结合tab水平制作符。
- for /f "delims=" %%i in (1.txt) do (
- set "str=%%i"
- set "str=!str: =#!"
- rem echo;!str!
-
- for /f "tokens=1-3 delims=#" %%a in ("!str!") do echo;%%a %%b %%c
-
- )
- pause
复制代码
作者: qixiaobin0715 时间: 2021-2-19 16:09
就题解题,前2列字符目视不超过30个字符,KG30的值取30个空格:- @echo off
- set KG30=
- setlocal enabledelayedexpansion
- for /f "tokens=1-3" %%a in (1.txt) do (
- set str=%%a%%b%KG30%
- set str=!str:~0,30!
- set str=!str:%%b=!%%b %%c
- echo !str!
- )
- pause
复制代码
作者: qixiaobin0715 时间: 2021-2-20 08:45
根据3楼思路改写,实现列与列之间空格最少:- @echo off
- setlocal enabledelayedexpansion
- set n=0
- for /f "tokens=1,2" %%i in (1.txt) do (
- set "var=%%i%%j"
- set m=0
- call :1
- )
- for /l %%x in (1,1,!n!) do set KG= !KG!
- set /a n+=1
- for /f "tokens=1-3" %%a in (1.txt) do (
- set str=%%a%%b%KG%
- for %%y in (!n!) do set str=!str:~0,%%y!
- set str=!str:%%b=!%%b %%c
- echo !str!
- )
- pause
- goto :eof
- :1
- if not "!var:~%m%,1!"=="" set /a m+=1&goto 1
- if %m% gtr %n% set n=%m%
- goto :eof
复制代码
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |