标题: [文本处理] [已解决]批处理或VBS如何实现对多个文本文件进查找替换字符串操作 [打印本页]
作者: syqh2010 时间: 2015-2-28 22:54 标题: [已解决]批处理或VBS如何实现对多个文本文件进查找替换字符串操作
本帖最后由 pcl_test 于 2016-7-15 13:07 编辑
感谢apang的帮助!!
根据a.txt中文件名依次修改相应文本内容。用sed、纯批、VBS都行
a.txt中内容为文件名
如:
599978.L
599978.R
、
、
文件内容相似如下:(以599978.L为例)- [EdgeCribbingTool]
- ToolSpeed=25000
- ToolSpeedMaster=25000
- Waviness=0.05
-
- [Generating]
- ToolSpeed=25000
- ToolSpeedMaster=25000
- Waviness=0.05
-
- [InitialData]
- Diameter=73
- Thickness=11.10
-
- [EdgeData]
- Type=circle
- Diameter=73
- 、
- 、
复制代码
希望改后效果如下:- [EdgeCribbingTool]
- ToolSpeed=25000
- ToolSpeedMaster=25000
- Waviness=0.05
-
- [Generating]
- ToolSpeed=5000
- ToolSpeedMaster=25000
- Waviness=0.05
-
- [InitialData]
- Diameter=73
- Thickness=11.10
-
- [EdgeData]
- Type=circle
- Diameter=80
- 、
- 、
复制代码
就像用VBA中有FOR遍历,用IF判断一样(只是举个例子,哪种方法快用哪种)- for所有文件
- if文件名=599978.L then
- 条件1
- if 找到[Generating] then
- if 找到ToolSpeed then
- ToolSpeed=原来的值*0.2
- end if
- end if
- 条件2
- if 找到[EdgeData] then
- if 找到Diameter then
- Diameter=80
- end if
- end if
- 、
- 、
- 条件n
- if***then
- ****
- end if
-
- end if
- next
复制代码
希望各位能帮忙,用sed,纯批都行,谢谢!
作者: pcl_test 时间: 2015-2-28 22:59
回复 1# syqh2010
599978.L
599978.R
……
这些文件的扩展名是什么?
作者: syqh2010 时间: 2015-2-28 23:05
回复 2# pcl_test
都是文本文档,用记事本可以直接打开。就跟
599978.txt
599978.txt
123456.txt
123456.txt
一样
作者: pcl_test 时间: 2015-3-1 01:09
回复 1# syqh2010 - @echo off
- setlocal enabledelayedexpansion
- for /f "delims=" %%a in ('type "a.txt"') do (
- set n=0
- for /f "tokens=1* delims=:" %%b in ('findstr /n .* "%%a"') do (
- >$ echo,%%c
- if !n! == 1 (
- for /f "tokens=2 delims==" %%d in ('type "$"') do set /a s=%%d/5
- >>"2.txt" echo,ToolSpeed=!s!
- set n=0
- ) else (
- >>"2.txt" echo,%%c
- )
- findstr /c:"Generating" $ >nul 2>nul && set n=1
- )
- del $
- move "2.txt" "%%a"
- )
-
- for /f "delims=" %%a in ('type "a.txt"') do (
- set n=0
- for /f "tokens=1* delims=:" %%b in ('findstr /n "EdgeData" "%%a"') do set /a t=%%b+1
- for /f "tokens=1* delims=:" %%c in ('findstr /n .* "%%a"') do (
- if !n! lss !t! (
- >>$1 echo,%%d
- ) else (
- >>$2 echo,%%d
- )
- set /a n+=1
- )
- set m=0
- for /f "tokens=1* delims=:" %%e in ('findstr /n .* "$2"') do (
- if not !m! == 0 >>$ echo,%%f
- set /a m+=1
- )
- move $ "$2"
- for /f "tokens=1* delims=:" %%g in ('findstr /n .* "$1"') do >>$ echo,%%h
- >>$ echo,Diameter=80
- for /f "tokens=1* delims=:" %%i in ('findstr /n .* "$2"') do >>$ echo,%%j
- move "$" "%%a"
- del $*
- )
- pause
复制代码
作者: syqh2010 时间: 2015-3-1 01:14
回复 4# pcl_test
非常感谢您的帮助,我试过后再给你反馈:)
作者: syqh2010 时间: 2015-3-1 01:31
回复 4# pcl_test
谢谢!能达到要求效果!
但感觉速度有些慢,因为实际情况需要同时修改几百个文件,且每个文件有200多行,且条件会多于2个。
如果能快一些,简洁一些(便于添加条件)就完美了!
谢谢!
作者: Batcher 时间: 2015-3-1 09:28
回复 6# syqh2010
请举例说明条件1、条件2是什么
作者: syqh2010 时间: 2015-3-1 09:41
条件1
if 找到[Generating] then
if 找到ToolSpeed then
ToolSpeed=原来的值*0.2
end if
end if
条件2
if 找到[EdgeData] then
if 找到Diameter then
Diameter=80
end if
end if
作者: apang 时间: 2015-3-1 17:19
本帖最后由 apang 于 2015-3-2 02:02 编辑
保存为test.bat,与a.txt放在同一目录- @set @n=0;// & cscript -nologo -e:jscript "%~0"<a.txt & pause & exit/b
-
- Path = "D:\\Test\\"
- fso = new ActiveXObject("Scripting.FileSystemObject");
- while (!WScript.StdIn.AtEndOfStream) {
- f = WScript.StdIn.ReadLine().replace(/^\s+|\s+$/g, "");
- f = Path + f;
- if (fso.FileExists(f)) {
- objFile = fso.OpenTextFile(f, 1);
- txt = objFile.ReadAll();
- objFile.Close();
- fso.OpenTextFile(f, 2).Write(changeNum(txt))
- }
- }
-
- function changeNum(s) {
- s += "\r\n";
- //ToolSpeed 的值乘以0.2
- re1 = /^( *\[Generating][\s\S]+?^ *ToolSpeed *=)(.*)\r\n/im;
- //Diameter 的值修改成80
- re2 = /^( *\[EdgeData][\s\S]+?^ *Diameter *=)(.*)\r\n/im;
- //Type=circle 修改为 Type=rand
- re3 = /^ *Type *= *circle *\r\n/im;
- //[EdgeData] 下面增加一行 PA=5.0
- re4 = /^ *\[EdgeData] *\r\n/im;
- //Wavi开头的行后面加上 -Q
- re5 = /^( *Wavi.*?)(\-Q)? *\r\n/img;
- //删除以Thickness开头的行
- re6 = /^ *Thickness.*\n/img;
- s = s.replace(re1,
- //加减除修改下面*为+-/
- function(s0,s1,s2){s2-=0; return s1 + (s2 * 0.2) + "\r\n"}
- );
- s = s.replace(re2, "$1" + "80" + "\r\n");
- s = s.replace(re3, "Type=rand" + "\r\n");
- s = s.replace(re4, "$&" + "PA=5.0" + "\r\n");
- s = s.replace(re5, "$1" + "-Q" + "\r\n");
- s = s.replace(re6, "");
- return s.replace(/\r\n$/, "")
- }
复制代码
作者: syqh2010 时间: 2015-3-1 20:02
回复 9# apang
谢谢,您的代码很好用,能快速达到效果。我是新手,研究下再给你反馈,谢谢!
作者: syqh2010 时间: 2015-3-1 21:37
本帖最后由 syqh2010 于 2015-3-1 21:41 编辑
回复 9# apang
再次感谢,代码很好用!
1)偶是小白,授之以鱼不如授之以渔。希望能对代码有些注释,然后自已可以添加修改。
如:
s0 = s0.replace(re1, function(s0, s1, s2) {
return s1 + s2 * 0.2 + "\r\n"
s0、s1、s2具体返回哪些值,
“s2 * 0.2”如何改为原值+200(如新值=原值+500),能+-*/
2)如何添加条件(在可以添加的地方备注下就好了)
如想将[InitialData]下的Diameter值改为65。模防了下好像不行啊。
function changeNum(s) {
s += "\r\n[";
re = /^ *\[[\s\S]+?(?=^ *\[)/mg;
re1 = /^( *\[Generating][\s\S]+^ *ToolSpeed *=)(.*)\r\n/im;
re2 = /^( *\[EdgeData][\s\S]+^ *Diameter *=)(.*)\r\n/im;
re3 = /^( *\[InitialData][\s\S]+^ *Diameter *=)(.*)\r\n/im;
此处添加查找项
s = s.replace(re, function(s0) {
s0 = s0.replace(re1, function(s0, s1, s2) {
return s1 + s2 * 0.2 + "\r\n"
});
s0 = s0.replace(re2, "$1" + "80" + "\r\n");
return s0
s0 = s0.replace(re3, "$1" + "98" + "\r\n");
return s0
此处添加对应修改项
})
return s.replace(/\r\n\[$/, "")
}
3)有重复的行可以用此法2次查找。没有重复的行可否直接查找
如“Type=circle”在文本中是唯一的,如何直接找到并修改为 “Type=rand”
4)如何加入路径
a.txt和BAT在同一目录下,需处理的文本在另一目录下如E:\mybat\ (最好能支持有空格其它字符的路径名)
5)如有可能,希望能此代码能成为一个模版,变得更实用。有增删改功能
如:
在[EdgeData]的下一行写入”PA=5.0"
检测以“Type”开头的行是否以“-Q”结尾(即Type*-Q),是就退出,不是就添加“-Q”
删除以”Thinkness"开头的行(能支持行开头有空格,特殊字符最好)
(sed很容易实现以上功能,能添加sed也行,只要能达到效果)
请恕问题太多,谢谢!!!
作者: apang 时间: 2015-3-1 23:57
回复 11# syqh2010
代码已修改。想要绝对通用是不可能也不现实的,只能具体问题具体分析
作者: syqh2010 时间: 2015-3-2 10:49
回复 9# apang
非常感谢,代码简洁有效,就是我想要的!
再多问一下:
能否支持模糊匹配文本名?
假如不提供完整的文本名,如a.txt中分别写入以下内容,运行后即将符合的更改?
599978.*
*599978*.L
*555978*.*
谢谢!
作者: syqh2010 时间: 2015-3-2 11:53
回复 9# apang
再请教一下,假如不要a.txt,把文件名直接写在代码中,如何改。
只改下面这句
Path = "D:\\Test\\599978.L"
也能修改,但会出现提示“microsoft****运行时错误,没有权限”
作者: apang 时间: 2015-3-2 18:39
回复 14# syqh2010 - @set @n=0;/* & echo off
- for /f "delims=:" %%a in ('findstr /bn "\/\*" "%~0"') do (
- more +%%a "%~0" | cscript -nologo -e:jscript "%~0"
- )
- pause & exit/b & rem */
-
- Path = "D:\\Test\\"
- fso = new ActiveXObject("Scripting.FileSystemObject");
- while (!WScript.StdIn.AtEndOfStream) {
- f = WScript.StdIn.ReadLine().replace(/^\s+|\s+$/g, "");
- f = Path + f;
- if (fso.FileExists(f)) {
- objFile = fso.OpenTextFile(f, 1);
- txt = objFile.ReadAll();
- objFile.Close();
- fso.OpenTextFile(f, 2).Write(changeNum(txt))
- }
- }
-
- function changeNum(s) {
- s += "\r\n";
- //ToolSpeed 的值乘以0.2
- re1 = /^( *\[Generating][\s\S]+?^ *ToolSpeed *=)(.*)\r\n/im;
- //Diameter 的值修改成80
- re2 = /^( *\[EdgeData][\s\S]+?^ *Diameter *=)(.*)\r\n/im;
- //Type=circle 修改为 Type=rand
- re3 = /^ *Type *= *circle *\r\n/im;
- //[EdgeData] 下面增加一行 PA=5.0
- re4 = /^ *\[EdgeData] *\r\n/im;
- //Wavi开头的行后面加上 -Q
- re5 = /^( *Wavi.*?)(\-Q)? *\r\n/img;
- //删除以Thickness开头的行
- re6 = /^ *Thickness.*\n/img;
- s = s.replace(re1,
- function(s0,s1,s2){s2-=0;return s1 + (s2 * 0.2) + "\r\n"}
- );
- s = s.replace(re2, "$1" + "80" + "\r\n");
- s = s.replace(re3, "Type=rand" + "\r\n");
- s = s.replace(re4, "$&" + "PA=5.0" + "\r\n");
- s = s.replace(re5, "$1" + "-Q" + "\r\n");
- s = s.replace(re6, "");
- return s.replace(/\r\n$/, "")
- }
-
- /* --- Start List ---
- 1.txt
- 2.txt
- 3.txt
- --- End List ------ */
复制代码
作者: apang 时间: 2015-3-2 18:41
回复 14# syqh2010
如果还有其它问题,请更新顶楼内容,或重新发贴
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |