批处理之家's Archiver

pusofalse 发表于 2008-7-25 21:11

【练习-003】批处理实现文本左右对齐排版

如1.txt内容如下。[code]111111111111111111111    98912 张三
222222222222222222    150020 李四四
  333333333333333333333    360000 王五
444444444444444444    2332 赵六六
  555555555555555555    222 田七
666666666666666666666    999999 舞吧[/code]通过批处理输出为:[code]
111111111111111111111      98912 张三
222222222222222222        150020 李四四
333333333333333333333     360000 王五
444444444444444444          2332 赵六六
555555555555555555           222 田七
666666666666666666666     999999 舞吧[/code]代码要求,不生成任何临时文件。
代码简洁,视思路与代码加分!
------------------------------------------------------------------------------------------
[color=blue]本题只是给出一个简单的文本通过批处理排版,而要求代码的通用,正如batman版主所说,会是一个繁琐的过程,于是就题解题,不必考虑代码的通用。[/color]

[[i] 本帖最后由 batman 于 2008-7-27 23:57 编辑 [/i]]

batman 发表于 2008-7-25 22:48

我来帮大家理思路吧:
所有的列其实都是左右对齐,大家想下为什么吧。

[[i] 本帖最后由 batman 于 2008-7-26 01:25 编辑 [/i]]

浅默 发表于 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

我本人的解,还是很繁琐,思路跟浅默的差不多。望更多人参与此题,求得更多的解!

[code]
@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
[/code]

fastslz 发表于 2008-7-26 18:11

这个是潜规则默认排版方式[code]@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[/code]

pusofalse 发表于 2008-7-26 18:22

[quote]原帖由 [i]fastslz[/i] 于 2008-7-26 18:11 发表 [url=http://bbs.bathome.net/redirect.php?goto=findpost&pid=5946&ptid=1246][img]http://bbs.bathome.net/images/common/back.gif[/img][/url]
这个是潜规则默认排版方式
@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 [/quote]

第一次看到如此的方法,还没弄明白怎么回事,在我电脑上测试着不正确。但仍旧学习了!~

fastslz 发表于 2008-7-26 18:35

是论坛字符问题
方法其实很简单call标签删除前面及后面的空格字符,替换空格字符为Tab键字符set "str=%str: =这里是Tab键字符%"
附上附件

pusofalse 发表于 2008-7-26 18:42

[quote]原帖由 [i]fastslz[/i] 于 2008-7-26 18:35 发表 [url=http://bbs.bathome.net/redirect.php?goto=findpost&pid=5949&ptid=1246][img]http://bbs.bathome.net/images/common/back.gif[/img][/url]
是论坛字符问题
方法其实很简单call标签删除前面及后面的空格字符,替换空格字符为Tab键字符set "str=%str: =这里是Tab键字符%"
附上附件 [/quote]
测试文本:
[code]1111111    aaaaaaaaaaaa 张三
222222sdf222222222222    150020 李四四
  3333333sfd33333333333333    0 王五
44444444444aa4444444    2332 赵sdfafa六六
  555555555    222 田七
666666666666666666666asaaaaaaaaa    9999999999999 舞[/code]

batman 发表于 2008-7-26 18:47

就题解题

个人认为如本题要充分考虑代码通用性的话,就会是一个相当复杂的过程,
于是,就题解题:[code]@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[/code]

batman 发表于 2008-7-26 19:04

[quote]原帖由 [i]fastslz[/i] 于 2008-7-26 18:35 发表 [url=http://bbs.bathome.net/redirect.php?goto=findpost&pid=5949&ptid=1246][img]http://bbs.bathome.net/images/common/back.gif[/img][/url]
是论坛字符问题
方法其实很简单call标签删除前面及后面的空格字符,替换空格字符为Tab键字符set "str=%str: =这里是Tab键字符%"
附上附件 [/quote]
使用制表符是默认的左对齐分列,主要用来从文本向excel中导数据。

风行者 发表于 2008-7-26 20:03

我是最最新手,向你们学习

[code]@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[/code]

pusofalse 发表于 2008-7-26 20:08

可以直接这样。。
echo 111111111111111111111      98912 张三
echo 222222222222222222        150020 李四四
echo 333333333333333333333     360000 王五
...
...
加分鼓励!一同进步!

batman 发表于 2008-7-26 20:17

[quote]原帖由 [i]风行者[/i] 于 2008-7-26 20:03 发表 [url=http://bbs.bathome.net/redirect.php?goto=findpost&pid=5954&ptid=1246][img]http://bbs.bathome.net/images/common/back.gif[/img][/url]
@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   ... [/quote]
这种解法的确是太可爱了,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

[code]@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[/code]

523066680 发表于 2008-8-12 11:17

我也行!

[code]
@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
[/code]

523066680 发表于 2008-8-12 14:13

我稍微换一下思路,应该说是尽量的通用了……如果某文本太过畸形 那也是没办法的事了……
文本内容更新为:[code]111111111111111111111                                      98912 张三
222222222222222222    150020 李四四
  333333333333333333333    360000 王五
4444444444444444444321542365445432453243243423432   11111143242342332 赵六六
  555555555555555555    222 田七
666666666666666666666    999999                                   舞吧[/code][code]@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[/code]原理:例如文本内容为:
ab******1*d
abc*************2********e
用for获得前面的两列
直接组合 则免去了中间的空格:
ab1
abc2
直接加上80个空格
ab1***************************……
abc2***************************……
然后保存前80位。
ab1*********……***
abc2********……***
把空格前移
ab*********……***1
abc********……***2
这样前面的就基本对齐了。后面的第三列 就不用说了…
我觉得应该可以了……至少我自己用不上太通用的,这个代码自己也没有当工具用过




[size=7]忽忽……加了中文 或者字符……就被淘汰了……[/size]

[[i] 本帖最后由 523066680 于 2008-8-12 15:49 编辑 [/i]]

terse 发表于 2008-8-12 18:37

我来个  补齐字符方法   效率不怎么样[code]@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[/code]

随风 发表于 2008-8-12 21:27

不知此帖是否够通用?不过创建了临时文件。
[url]http://bbs.bathome.net/viewthread.php?tid=1042&highlight=%C5%C5[/url]

weichenxiehou 发表于 2010-12-30 22:11

新接触批处理,很有意思,请各位大侠多多指教。在此送上我的代码,多多指教!既然各位大侠都说了就题解题,那不好意思了,嘿嘿……

[code]
@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!
)
[/code]

[[i] 本帖最后由 weichenxiehou 于 2010-12-30 23:37 编辑 [/i]]

vincentzhou 发表于 2011-1-9 15:01

[code]@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
) [/code]

CrLf 发表于 2011-2-22 18:46

下载了10楼附件,可是还是没效果啊,莫非win7不支持这样么...

shelluserwlb 发表于 2014-12-17 23:41

[code]@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 [/code]效果见下图:

bailong360 发表于 2015-3-15 09:04

[code]@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
)[/code]

尘丶 发表于 2015-9-18 17:51

[code]@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[/code]

依山居 发表于 2015-11-4 12:38

[code]# 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 舞吧
'''

[/code]

页: [1] 2

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.