找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 131918|回复: 56

【练习-007】批处理去除指定字符前所有的0

[复制链接]
发表于 2008-8-1 22:37:35 | 显示全部楼层 |阅读模式

如文本1.txt:
  1. 0000acb0h
  2. 0b0c00a000s
  3. 0000h00ga00
  4. a0000000
复制代码
通过批处理将文本所有字符串字符a前的0去除输出如下:
  1. acb0h
  2. bca000s
  3. hga00
  4. a0000000
复制代码
要求:代码简洁、高效、通用,不生成临时文件
-----------------------------------------------------
本题已有较完美的解答方案:
  见9楼pusefalse版主和本人10楼的方案。


[ 本帖最后由 batman 于 2008-8-4 17:55 编辑 ]
发表于 2008-8-2 00:12:33 | 显示全部楼层
********************
屏蔽,看错题意了。

[ 本帖最后由 pusofalse 于 2008-8-2 04:20 编辑 ]
发表于 2008-8-2 01:15:32 | 显示全部楼层
我失败了,但我有个问题
我的测试代码如下:
  1. @echo off
  2. for /f "tokens=1,2 delims=a" %%i in (1.txt) do (
  3. set a=%%i
  4. set a=%a:0=%
  5. echo %a%a%%j
  6. )
复制代码


结果为:

  1. acb0h
  2. a000s
  3. a00
  4. a
复制代码


在CMD中运行
set a=0b0c00a000s
set a=%a:0=%
echo %a%
的结果正常,显示为:bcas
为什么在上面的测试代码中结果却全部变没了呢?
发表于 2008-8-2 04:05:28 | 显示全部楼层
原帖由 null 于 2008-8-2 01:15 发表
我失败了,但我有个问题
我的测试代码如下:
@echo off
for /f "tokens=1,2 delims=a" %%i in (1.txt) do (
set a=%%i
set a=%a:0=%
echo %a%a%%j
)

结果为:

acb0h
a000s
a00
a


在CMD中运行
...

你的这两个代码输出的结果是理所当然的。第一个因为没有开启变量延迟,即使开启了,输出的结果也不会正确。
第二个。你测试如下代码。

  1. set a=0b0c00a000s&echo %a%
  2. pause
复制代码
保存为bat。运行,你会发现a的值并不是你所想的那样,而是显示echo处于关闭状态。
这是因为CMD命令解释器在读到set a=0b0c00a000s&echo %a%这一条完整的语句时,发现a用%%闭合,是个变量,会把它替换成之前所赋给它的字符串常量,并把它打印出来。而在这条完整的语句之前并没有给a赋值,即是空值。所以才会显示echo处于关闭状态。请理解“一条完整的语句”的意思。
set a=0b0c00a00s&echo %a% 这才是一条完整的语句。
同样的,for语句中给a赋值,然后又在for中引用%a%,在这之前,CMD早就把它替换为空值了,所以你的代码会出错。
如何避免这种出错呢,要用到变量延迟了。
setlocal enabledelayedexpansion 这条语句的意思即是开启变量延迟。它的作用就是要告诉CMD,在读到一条完整的语句时,不要急匆匆地扩展变量。而是在执行复合语句(for语句或if语句中其后用一对圆括号闭合的所有语句称为复合语句,用&或&&连接的也是复合语句。)中的某单条语句之后,再执行变量的扩展,也就是说,这个变量扩展的行为被延后了。在开启延迟之后,在for中给变量a赋值,又在for中引用a,此时,就不应用%%将其闭合了,而是用!!。
你的代码应该是这样。

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1,2 delims=a" %%i in (1.txt) do (
  3. set a=%%i
  4. set a=!a:0=!
  5. echo !a!a%%j
  6. )
  7. pause
复制代码
但输出的结果仍不符合楼主的要求,这就要看你的了。

还要记得,如果在复合语句之外再次引用变量,此时它的值是在复合语句之内最后得到的值。
如下代码:

  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (100 1 199) do set var=%%a&echo !var:~1!
  3. echo %var%
  4. pause
复制代码
关于变量延迟,搜索一下,多做测试很快就能明白了,我说的很粗糙。

[ 本帖最后由 pusofalse 于 2008-8-2 04:06 编辑 ]
发表于 2008-8-2 11:07:54 | 显示全部楼层

回复 4楼 的帖子

我明白了,十分感谢!
 楼主| 发表于 2008-8-2 12:00:51 | 显示全部楼层
提示一下:
  开启变量延迟是我们常用的方法,但大家想一想本题是不是可以不开变量延迟?
 楼主| 发表于 2008-8-3 13:36:42 | 显示全部楼层
我们出题目的目的在于让大家都活跃下思路,在设法解题的过程中能得到提高。

本题确实不难,希望大家充分利用好每次出题的机会来提高自己,同时也可获
得一定的积分奖励(当然这并不是目的所在)。
发表于 2008-8-3 14:32:10 | 显示全部楼层
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "usebackq skip=12 delims=" %%a in ("%~dpnx0") do (
  3.         set "var=%%a"
  4.         set "var=!var:a=a#!"
  5.         for /f "tokens=1* delims=#" %%i in ("!var!") do (
  6.                  set "eo1=%%i"&set "eo2=%%j"
  7.                  set "eo1=!eo1:0=!"
  8.                  set "eo2=!eo2:#=!"
  9.                  echo.!eo1!!eo2!
  10.             )
  11.     )
  12. pause&goto :eof
  13. 0000acb0ha0
  14. 0b0c00a000s
  15. 0000h00ga00
  16. a0000000a
  17. a00d0sa000d0a0
复制代码

[ 本帖最后由 ieutk 于 2008-8-3 15:09 编辑 ]

评分

参与人数 1PB +3 收起 理由
batman + 3 代码复杂了点

查看全部评分

发表于 2008-8-3 18:40:07 | 显示全部楼层
  1. @echo off
  2. for /f "delims=" %%. in (1.txt) do (
  3.    set "str=%%."
  4.    call,set "str=%%str:*a=%%"
  5.    for /f "delims=a" %%{ in ("%%.") do (
  6.          set "var=%%{"
  7.         call,echo.%%var:0=%%a%%str%%
  8.   ))
  9. pause>nul
复制代码


来个怪异的。^_^

评分

参与人数 3PB +28 收起 理由
ieutk + 12 代码简洁,通用
more + 6
batman + 10 充分利用delims,好!

查看全部评分

 楼主| 发表于 2008-8-4 17:52:01 | 显示全部楼层
我的解:
  1. @echo off
  2. for /f "tokens=1,2 delims=a" %%i in (1.txt) do (
  3.      if "%%j" neq "" (
  4.         set "str=%%i"
  5.         call,set "str=%%str:0=%%"
  6.         call,echo %%str%%a%%j
  7.         ) else (
  8.         echo a%%i
  9.      )
  10. )
  11. pause>nul
复制代码

评分

参与人数 1PB +6 收起 理由
keen + 6 牛就一个字!!!

查看全部评分

发表于 2008-8-5 11:55:51 | 显示全部楼层
如果测试文本如下,要求去除第一个a前的0,那么只有9楼的代码成功:
  1. 0000acb0a0h
  2. 0ab0c00a000s
  3. 0000h00ga00
  4. 00a000a0000
复制代码

[ 本帖最后由 more 于 2008-8-5 11:59 编辑 ]
 楼主| 发表于 2008-8-5 12:56:14 | 显示全部楼层
批处理之所以如此得到大家的青睐,是因为它可以现写现用很方便,
同时从一另一层面上就要求我们具体问题具体对待,相信谁也不会
回为要解决一个普通的问题而写出一个适合出所有此类问题的代码
吧,如真要这样做,在时间上的损耗将是一笔无可估量的损失,我
们也会因此而得不偿失。

评分

参与人数 1PB +4 收起 理由
more + 4 是我想复杂了

查看全部评分

发表于 2008-8-5 13:36:24 | 显示全部楼层
如果测试文本如下,要求去除第一个a前的0,那么只有9楼的代码成功


用11楼提供的字符经测试,8,9楼代码都通过,10楼没有通过


批处理之所以如此得到大家的青睐,是因为它可以现写现用很方便,
同时从一另一层面上就要求我们具体问题具体对待,相信谁也不会
回为要解决一个普通的问题而写出一个适合出所有此类问题的代码
吧,如真要这样做,在时间上的损耗将是一笔无可估量的损失,我
们也会因此而得不偿失。


呵呵,说的也是,有时在写代码的时候会出现考滤问题不全而导致代码不通用。
发表于 2008-8-5 21:20:06 | 显示全部楼层
可怜的我为什么都学不会for的用法??
各位大大怎么学的??
发表于 2008-8-5 21:52:38 | 显示全部楼层

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1,2 delims=a" %%i in (1.txt) do (
  3. set aftera=%%j
  4. if "!aftera!"=="" set aftera=%%i
  5. set a=%%i
  6. set a=!a:0=!
  7. echo !a!a!aftera!
  8. )
  9. pause
复制代码

[ 本帖最后由 shqf 于 2008-8-5 21:57 编辑 ]

评分

参与人数 1PB +3 收起 理由
batman + 3 加油

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 01:44 , Processed in 0.022962 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表