中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-06-17 19:47
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [已结]setlocal EnableDelayedExpansion 与 "!" 查看 9,309 回复 25
16 发表于 2006-06-19 13:26 ·  中国 北京 鹏博士BGP
中级用户
★★
积分 404
发帖 179
注册 2006-03-30 14:44
UID 53056
状态 离线
拜托 再帮我看看吧
17 发表于 2006-06-19 18:58 ·  中国 山西 临汾 中移铁通
元老会员
★★★★
Batchinger
积分 4,432
发帖 1,512
注册 2002-10-18 00:00
UID 19
性别 男
状态 离线
Re kcdsw:

抱歉!你的问题我很快就注意到了,但是遗憾的是,当时和后来我做了许多的测试,结果证明使用for+echo的方法复制和编辑文本存在很多问题,尤其是对类似cover.ps这类含有相当多特殊字符的文件。

于是我准备改弦更张,使用其它的方法编辑文本。

第一个想到的方法是edlin,因为它是NT系列自带的命令行方式的文本编辑器,结果费了一番工夫之后,发现edlin不能处理超长的文件,文件只加载到530多行便结束了。

于是,所余的路径便只有第三方脚本工具了。考虑到只是替换一些简单的文本,所以选择了sed,其脚本编写起来并不繁琐。使用GNU sed 3.02测试了以下代码,结果是正确且高效的。


@echo off

::取原始的位置参数
::for /f "tokens=1,2,3,4,5,6,7" %%a in ('findstr /C:"DeviceRGB" cover.ps') do set jpg=%%a %%b %%c %%d %%e %%f %%g

::取图片的象素值进行判断
for /f "tokens=2,3" %%h in ('findstr /C:"setcolorspace" cover.ps') do (
if %%h EQU %%i echo 封面中的作者照片无须更改!
if %%h LSS %%i echo 照片不规则!
if %%h GTR %%i set /a newsize=730*%%h/%%i
)

::::获取所在行行号和内容
::for /f "tokens=1,* delims=:" %%m in ('findstr /N /C:"730 730" temp.ps') do (
:: set iLN=%%m
:: set sLine=%%n
::)
::
::set sLine=%sLine:730 730=!newsize! 730%
::
::echo %iLn%d> _temp.edl
::echo i%iLn%>> _temp.edl
::echo %sLine%>> _temp.edl
::echo >> _temp.edl
::echo %iLn%,%iLn%l>> _temp.edl
::echo e>> _temp.edl
::
::edlin cover.ps < _temp.edl

:: 将新的大小写入指定行
if %newsize% NEQ 0 sed -e "s/\(.*\)730\( 730.*\)/\1%newsize%\2/" cover.ps >cover3.txt


[ Last edited by willsort on 2006-6-20 at 10:31 ]
※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得!
18 发表于 2006-06-20 10:15 ·  中国 北京 鹏博士BGP
中级用户
★★
积分 404
发帖 179
注册 2006-03-30 14:44
UID 53056
状态 离线
@echo off 
setlocal EnableDelayedExpansion

::取原始的位置参数
for /f "tokens=1,2,3,4,5,6,7" %%a in ('findstr /C:"DeviceRGB" cover.ps') do set jpg=%%a %%b %%c %%d %%e %%f %%g

::取图片的象素值进行判断
for /f "tokens=2,3" %%h in ('findstr /C:"setcolorspace" cover.ps') do (
if %%h EQU %%i echo 封面中的作者照片无须更改!
if %%h LSS %%i echo 照片不规则!
if %%h GTR %%i set /a newsize=730*%%h/%%i
)

:: 将新的大小写入指定行
if %newsize% NEQ 0 sed -e "s/\(.*\)730\( 730.*\)/\1%newsize%\2/" cover.ps >cover3.txt


那这样写的话是不是只是替换了原先的730 730 ?
如果是这样,那我第一行的for 是不是可以不要了?
只需要提取出象素大小,然后计算出所需的新数据 然后替换?


能否提供你所说的sed的版本下载?

[ Last edited by kcdsw on 2006-6-20 at 10:29 ]
19 发表于 2006-06-20 10:30 ·  中国 山西 大同 中移铁通
元老会员
★★★★
Batchinger
积分 4,432
发帖 1,512
注册 2002-10-18 00:00
UID 19
性别 男
状态 离线
Re kcdsw:

没错,是这样的。

原代码中第一个for语句,是在考虑for+echo和edlin方案时使用的,改用sed方案后因其不影响结果输出,而忽略了将其删除。类似的语句还有setlocal。

现已将原代码进行了修改。

sed下载链接请参考,请注意使用GNU sed 4.0.7会过滤掉文本行中的回车符(0x0D),生成Unix格式文本。GNU sed 3.02 则没有这个问题。

GNU utilities for Win32
http://unxutils.sourceforge.net/

[ Last edited by willsort on 2006-6-20 at 10:39 ]
※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得!
20 发表于 2006-06-20 11:33 ·  中国 北京 鹏博士BGP
中级用户
★★
积分 404
发帖 179
注册 2006-03-30 14:44
UID 53056
状态 离线
呵呵 谢谢版主

先前我很固执的要用批处理,可能是我的心理在做怪
总是觉得外来的程序大多没中文注解,也不是自己写的,也不放心,难学难懂
今天一用 感觉不错
21 发表于 2006-06-20 11:37 ·  中国 北京 鹏博士BGP
中级用户
★★
积分 404
发帖 179
注册 2006-03-30 14:44
UID 53056
状态 离线
用 QuickBFC 编译了一下

编译的时候把sed捆绑进去了

因为编译后的exe在运行的时候首先需要把原先的bat文件释放出来,位置是%temp%
我想 它释放捆绑文件的路径大概也是这里,或者是exe所在的文件夹
这样 exe会自动把cover.ps的路径传递给bat 和 sed ,那我就是更省心了,省的sed和bat不在一起.省的我告诉它cover.ps的路径,省了N多事情哇!!!

在此 再次感谢版主和各位关注我帖子的兄弟!!

受小弟一拜!!
22 发表于 2007-03-17 23:34 ·  中国 上海 黄浦区 电信
初级用户
积分 49
发帖 22
注册 2005-08-04 13:44
UID 41332
性别 男
状态 离线
好难不懂
23 发表于 2007-05-13 12:31 ·  中国 广东 广州 天河区 电信
新手上路
积分 4
发帖 2
注册 2007-05-13 11:22
UID 88381
性别 男
状态 离线
好多高手!!!!!!倾慕中....
24 发表于 2007-10-12 22:23 ·  中国 浙江 温州 电信
初级用户
★★
积分 158
发帖 89
注册 2007-04-25 08:06
UID 86402
性别 男
状态 离线
牛BI。顶上去。
25 发表于 2008-10-31 13:54 ·  中国 湖南 长沙 联通
新手上路
积分 4
发帖 3
注册 2007-11-03 01:05
UID 101547
性别 男
状态 离线
稀里糊涂的,下下来看下。
26 发表于 2008-11-20 23:00 ·  中国 山东 青岛 联通
新手上路
积分 1
发帖 1
注册 2008-11-18 22:56
UID 131398
性别 男
状态 离线
下来看看
论坛跳转: