中国DOS联盟论坛

中国DOS联盟

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

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

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » (已结,使用sed)批处理替换文本内容的难题
« [1] [2] »
作者:
标题: (已结,使用sed)批处理替换文本内容的难题 上一主题 | 下一主题
sh_en
初级用户




积分 132
发帖 7
注册 2005-4-27
状态 离线
『楼 主』:  (已结,使用sed)批处理替换文本内容的难题

有一个几十K的文本文件chrome.rdf,其中包含着很多行如下的内容:
C:/Documents%20and%20Settings/Administrator/Application%20Data/Mozilla/Firefox/Profiles/9ny06whv.default

怎么才能将以上内容替换为当前路径,如:D:\program files\mozilla\firefox\profiles

路径是不确定,要求在2000以上nt系统中实现上述替换。

我用了第三方文本替换工具如hexc、change、binsub、gsar等都不能替换成功,原因是替换内容超过了127个字符限制,运行脚本时会出错,提示说:找不到程序。且上述内容中含有“/"、”\“、"%"等特殊字符。

请高手们指教。

[ Last edited by willsort on 2005-9-22 at 18:57 ]

2005-9-11 11:56
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
sh_en
初级用户




积分 132
发帖 7
注册 2005-4-27
状态 离线
『第 2 楼』:  

在众多文本替换工具中,binsub号称可以查找、替换超过2000字符,前提是运用前缀@,以下是binsub的文档说明:
BINSUB 1.8 (c)1994 by Peter Enzerink. May be freely distributed.

TARGET

DOS:    MSDOS 3.0 +
CPU:    386 +

INTRODUCTION

Not all that complicated, but I find I use this tool all the time!

Basically it will let you search any type of file for any type of string,
up to about two thousand characters in length, and replace it with another
string of variable length up to 4096 characters.

Since DOS does not allow a command line to have more than 127 characters,
you may prefix the old or new pattern with an '@'. This will tell BINSUB
to look for a file called {oldpattern} and use its contents as the search
string. Likewise with the new pattern.

You can search for binary patterns and nonprinting characters by specifying
each character with a special format:

/nnn    where nnn is a three digit decimal number representing the ASCII
        value of the character.

An example use:

BINSUB CONFIG.SYS fcbs=4,1/013/010 fcbs=1,0/013/010lastdrive=z/013/010

This will modify the fcbs parameter in the file, and also insert a lastdrive
statement between the fcbs line and the next line in the file.

If the search or replace string has spaces in it, you can surround the
text with quotes, or use /032 for spaces. (Quotes would be faster)

You cannot include a simple '/' in your search or replace text, since the
program will assume you are attempting a substitution! You should use
/047 whenever you wish to search or replace a '/'.

COMMAND LINE OPTIONS

You may add a /I to the end of the command line to make the search case
insensitive. This is particularly useful in text files.

可是,我怎么试也不会成功,可能是我不会binsub的替换语法。
现附上binsub程序,让大家看看。

附件 1: binsub.zip (2005-9-11 12:07, 8.92 K, 下载附件所需积分 1 点 ,下载次数: 77)
2005-9-11 12:07
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 3 楼』:  

Re sh_en:

      就你的问题而言,我认为 hexc 应该是可以实现的,只是要分成多步骤进行:

      1. hexc chrome.rdf _temp.1 "/" "\"
      2. hexc _temp.1 _temp.2 "%20" 20
      批处理中 %20 应改为 %%20
      3. hexc _temp.2 _temp.3 "C:\Documents and Settings\Administrator\Application Data\" "D:\program files\"
      可能需要改成
         hexc _temp.2 _temp.3 "C:\Documents"20"and"20" Settings\Administrator\Application"20"Data\" "D:\program"20"files\"
      4.其它可能存在的替换工作。

      其它的文本替换工具也应该可以类似实现,每一次替换命令行都不会超出128字节,而且NT系列系统的命令行环境中其命令行长度应该不止128才对。

[ Last edited by willsort on 2005-9-11 at 16:24 ]



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-9-11 12:10
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
sh_en
初级用户




积分 132
发帖 7
注册 2005-4-27
状态 离线
『第 4 楼』:  

谢谢willsort大师指点。
按大师思路,我编写了如下脚本,成功实现了替换:

  Quote:
@echo off
rem 该脚本要在nt系统中运行。

rem  获取当前路径存入临时文件:
for /f "tokens=* delims=" %%a in ('cd ') do (
        echo %%a>tmp.tmp
    )

rem  转换路径"\"为"/"并将可能含有空格的路径加上"%20",并存入临时文件:
setlocal ENABLEDELAYEDEXPANSION
for /f "tokens=* delims=" %%i in (tmp.tmp) do (
        set n=%%i
        set n=!n:\=/!
        set n=!n: =%%20!
        echo !n!>>tmp1.tmp
    )
endlocal

rem  获取chrome.rdf文件中特定行的路径信息并存入临时文件:
for /f "tokens=2 delims==" %%i in ('findstr /c:"jar:file:///" chrome.rdf ^| findstr /n "." ^| findstr /r "^1:"') do (
        echo "%%i" >_tmp.tmp
    )

rem  将上步获取的路径信息中的特定字符替换为“+”,以便进一步提取有效路径,并存入临时文件:
setlocal ENABLEDELAYEDEXPANSION
for /f  %%i in (_tmp.tmp) do (
        set n=%%i
        set n=!n:///=+!
        set n=!n:extensions=+!
        echo "!n!" >_tmp1.tmp
    )
endlocal

rem  提取真实路径并存入临时文件:
for /f "tokens=2 delims=+" %%i in (_tmp1.tmp) do (
        echo %%i >_tmp2.tmp
    )

rem  读取路径信息并将chrome.rdf中的长路径分两步替换为"+":   
for /f "tokens=1-4,* delims=/" %%a in (_tmp2.tmp) do (
echo %%e > _tmp3.tmp
hexc chrome.rdf tmp_1.tmp "%%a/%%b/%%c/%%d" "+"
   )

for /f  %%n in (_tmp3.tmp) do (
hexc tmp_1.tmp tmp_2.tmp "/%%n" "+"
   )

rem  最后将tmp_2.tmp中的所有路径替换为当前路径。
for /f  %%i in (tmp1.tmp) do (
        hexc tmp_2.tmp chrome1.rdf "++" "%%i/Profiles/"
   )

rem  清理临时文件:
del *.tmp

但又有新问题:chrome.rdf中的路径也是不确定的,如果路径中的目录层数少于4层,就会导致替换错误。这使得该脚本的编写没有通用性。

我始终觉得一次性将路径替换才是实用的办法,只可惜号称可以替换2000多字符的binsub我不会用。

下面贴上chrome.rdf文件:

附件 1: chrome.rdf.zip (2005-9-13 09:17, 8.66 K, 下载附件所需积分 1 点 ,下载次数: 33)
2005-9-13 09:17
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 5 楼』:  

Re sh_en:

      分析和理解你的代码意图,消耗了我若干精力,最后我放弃了努力。因此,先仅就代码本身提供一些建议。

      首先,在NT系统的环境中,%cd%即代表当前路径,不需要提取cd的输出。
      其次,提取chrome.rdf路径可以直接用for的字符串解析功能,它也可以做到取一次路径便结束。
      再次,最后的路径替换可以用set的取固定位置和长度的子串功能,以此分两次或三次取得固定长度的路径串,然后依照你以前的思路分步替换。

      最后,就批处理之外的问题与兄讨论一下:

      1、程序之所以要分步替换,似乎是因为 CMD 为16位老程序分配的命令行缓冲区不够长(大约就是128的限制),而对于自身的内部命令和其他32位程序则无此限制,我们要实现一次替换,需要突破这个限制,因而需在CMD上做文章。

      2、我现在还不清楚你为何要使用批处理实现这次串替换,据我所知,许多编辑器或其它软件已经支持多文件全局替换,而且长度限制也要宽松许多。

      3、另外,不知兄是否尝试过用for+set实现所用的替换?

[ Last edited by willsort on 2005-9-13 at 16:17 ]



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-9-13 16:14
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
tigerpower
中级用户

大师兄


积分 377
发帖 99
注册 2005-8-26
状态 离线
『第 6 楼』:  

到底要干吗,是不是只要把file:///....../extensions/替换成file:///当前目录/extensions/就可以了

2005-9-13 21:02
查看资料  发短消息 网志   编辑帖子  回复  引用回复
sh_en
初级用户




积分 132
发帖 7
注册 2005-4-27
状态 离线
『第 7 楼』:  



  Quote:
Originally posted by tigerpower at 2005-9-13 09:02 PM:
到底要干吗,是不是只要把file:///....../extensions/替换成file:///当前目录/extensions/就可以了

对,目的是想将firefox浏览器做成绿色插件版。

Re willsort大师:
我有尝试过用for+set实现所用的替换,但set替换有个死穴,就是对于带有半角"!"号的文本行不能正确替换,有时会导致丢失若干字符。且set替换要用到重定向,它是将chrome.rdf文件推倒了重建,速度较慢。而hexc等第三方工具替换速度则很快。

再次感谢您对本贴的关注和解答!

2005-9-13 23:51
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
tigerpower
中级用户

大师兄


积分 377
发帖 99
注册 2005-8-26
状态 离线
『第 8 楼』:  

在xp下使用sed

@for /f %%i in ('echo %cd%^|sed -e "s/ /%%20/g"^|sed -e "s/\\/\//g"') do @set cwd=%%i
@sed -e "s$file:///.*/extensions/$file:///%cwd%/extensions/$g" Chrome.rdf

2005-9-14 07:56
查看资料  发短消息 网志   编辑帖子  回复  引用回复
xjhlhb
高级用户




积分 736
发帖 210
注册 2004-4-12
来自 中國
状态 离线
『第 9 楼』:  

若不能实现,建议利用
ECHO 命令 >>文件名
重新建立一个文件然后重新命名替换该文件也是可以的呀!

2005-9-14 16:46
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (35404766)  编辑帖子  回复  引用回复
sh_en
初级用户




积分 132
发帖 7
注册 2005-4-27
状态 离线
『第 10 楼』:  



  Quote:
Originally posted by tigerpower at 2005-9-14 07:56 AM:
在xp下使用sed

@for /f %%i in ('echo %cd%^|sed -e "s/ /%%20/g"^|sed -e "s/\\/\//g"') do @set cwd=%%i
@sed -e "s$file:///.*/extensions/$file:///%cwd%/extensions/$g&qu ...

强!实在是强!短短的两行代码,解决了许多问题。想不到sed功能这么强悍,tigerpower能推荐一些sed的学习资料吗?

2005-9-14 23:51
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
Climbing
铂金会员

网络独行侠


积分 6962
发帖 2753
注册 2003-4-16
来自 河北保定
状态 离线
『第 11 楼』:  

终于在DOS联盟又看到一位使用sed的高手,以前曾经出现过一位twf_cc朋友。

Re: sh_en
在置顶精华帖子汇总中有一个链接是介绍sed的用法的。里面提供有相关的网址。

sed -e "s$file:///.*/extensions/$file:///%cwd%/extensions/$g"

这一句很难懂,但只要理解了s$后面的"$"字符(包括后面所有的$字符)是用来代替默认的"/"分隔符的就容易懂了,为了看懂这个句子,我查了至少一个小时的sed使用帮助。



偶只喜欢回答那些标题和描述都很清晰的帖子!
如想解决问题,请认真学习“这个帖子”和“这个帖子”并努力遵守,如果可能,请告诉更多的人!
2005-9-15 02:38
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (653668)  编辑帖子  回复  引用回复
buddiyar
初级用户





积分 160
发帖 75
注册 2006-6-28
状态 离线
『第 12 楼』:  

我很长时间没看电脑杂志了
竟不知道xp下都有sed这等强悍的命令!

哎 落伍了哦

2006-7-16 13:59
查看资料  发送邮件  发短消息 网志  OICQ (243589543)  编辑帖子  回复  引用回复
flying008
中级用户





积分 245
发帖 103
注册 2006-6-30
状态 离线
『第 13 楼』:  

偶的P和WIN2000的命令行内输入SED怎么都提示没有这个命令???

2006-7-17 08:35
查看资料  发短消息 网志   编辑帖子  回复  引用回复
mrhjzhang
初级用户





积分 100
发帖 39
注册 2005-10-27
状态 离线
『第 14 楼』:  



  Quote:
Originally posted by Climbing at 2005-9-15 02:38:
终于在DOS联盟又看到一位使用sed的高手,以前曾经出现过一位twf_cc朋友。

Re: sh_en
在置顶精华帖子汇总中有一个链接是介绍sed的用法的。里面提供有 ...

置顶精华帖子汇总?找不到啊。还有,大大能给我一个win下的sed.exe吗?

2006-10-14 00:47
查看资料  发短消息 网志   编辑帖子  回复  引用回复
mrhjzhang
初级用户





积分 100
发帖 39
注册 2005-10-27
状态 离线
『第 15 楼』:  

sed最新版本是4.1.5可惜只有unix下能编译。
那位大大能给我个4.1.5吗?

2006-10-14 03:33
查看资料  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: