返回列表 发帖

[文本处理] 【已解决】批处理查找并替换字符串

本帖最后由 yearharvest 于 2013-11-8 21:59 编辑

把当前文件夹中指定后缀名的文件中的所有类似\pos(x,y)的字符串(x和y都是数字)替换成\pos(m*x,n*y),m和n也是数字。也就是字符串\pos(x,y)中的x和y乘上一个倍数。能支持各种文件编码

比如说a.txt里
\pos(100,200)\pos(100,200)\pos(100,200)
\pos(100,200)\pos(100,200)
\pos(100,200)COPY
x乘1.5,y乘2的话变成
\pos(150,400)\pos(150,400)\pos(150,400)
\pos(150,400)\pos(150,400)
\pos(150,400)COPY
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

@echo off
set n=2
for /f "delims=" %%F in ('dir /b /a-d *.ini') do (
    (for /f "usebackq delims=" %%i in ("%%F") do (
         set "str=%%i"
         setlocal enabledelayedexpansion
         if "!str:\pos=(!" neq "%%i" (
            for /f "tokens=1,2 delims=,)" %%a in ("!str:*\pos(=!") do (
                set /a "i=%%a*n,j=%%b*n" 2>nul&&(
                    for /f %%j in ("\pos(!i!,!j!)") do (
                        set "str=!str:\pos(%%a,%%b)=%%j!"
                    )   
                )
            )
        )
    for /f "delims=" %%i in ("!str!") do endlocal&echo %%i
    ))>$
    move $ "%%F"
)
pauseCOPY

TOP

本帖最后由 apang 于 2013-10-31 18:43 编辑

纯练习
Set fso = CreateObject("Scripting.FileSystemObject")
text = fso.OpenTextFile("a.txt").Readall
Set re = New RegExp
re.Pattern = "([\s\S]*?\\pos\()(\d+),(\d+)\)|([\s\S]+)$"
re.IgnoreCase = True
re.Global = True
For Each a In re.Execute(text)
    If a.SubMatches(3) = "" Then
        str = str & a.SubMatches(0) & _
        a.SubMatches(1) * 2 & "," & _
        a.SubMatches(2) * 2 & ")"
    Else str = str & a.SubMatches(3)
    End If
Next
fso.OpenTextFile("b.txt",2,True).Write strCOPY

TOP

两个方法处理下面这个文件都有问题,用2楼的处理后变成空文件,用3楼的报错“无效的过程调用或参数”,好像是因为编码的原因,然后我把编码转换成UTF-8,但是用2楼和3楼处理后都会乱码,请问这要怎么解决?
还有3楼的有没有办法像2楼可以处理同一后缀名的多个文件?

TOP

回复 4# yearharvest


    附件是unicode编码,第2行改成 text = fso.OpenTextFile("a.txt",1,,-1).Readall

TOP

回复 4# yearharvest
@echo off
set n=2
for /f "delims=" %%F in ('dir /b /a-d *.txt') do (
    (for /f "delims=" %%i in ('type "%%F"^|findstr /n .*') do (
        set "str=%%i"
        setlocal enabledelayedexpansion
        if "!str:\pos=(!" neq "%%i" (
           for /f "tokens=1,2 delims=,)" %%a in ("!str:*\pos(=!") do (
               set /a "i=%%a*n,j=%%b*n" 2>nul&&(
                   for /f %%j in ("\pos(!i!,!j!)") do (
                       set "str=!str:\pos(%%a,%%b)=%%j!"
                   )
               )
           )
        )
          echo;!str:*:=!
          endlocal
     ))>$
          move $ "%%F"
)
pauseCOPY

TOP

回复 5# apang


  编码是UTF-8的话又乱码了

TOP

回复 6# terse


    不支持小数,如果我要乘1.5的话就不行了,不过这是批处理本身不支持小数的原因,有没有其他办法支持小数?

TOP

回复 8# yearharvest
没什么好办法 如你所说 CMD不支持浮点,要么这样,1.5 你当作 15 去乘 然后除以10
1.5*32= 15 *32/10 = 48 这样近似了

TOP

帖子内容很好,学习了。

TOP

回复 8# yearharvest


    论坛搜索浮点数,有现成的代码。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

回复 7# yearharvest


    你的文件夹里到底有几种编码类型的文件需要修改?不说清楚要别人去猜呀?

你如果是真心求助的话,把你最终的需求更新到顶楼,我可以尝试一下,帮你写一段支持utf-8的代码。

TOP

@set @n=0//& dir /b *.txt | cscript.exe -nologo -e:jscript "%~f0" &pause&exit/b
while (!WSH.StdIn.AtEndOfStream) {
    f = WSH.StdIn.ReadLine();
    WSH.StdOut.Write("\r处理:\t"+f);
    WSH.Sleep(300); //Delete this line!
    try {enlarge(f, 1.5, 2.5); WSH.StdOut.Write("\r成功:\n");}
    catch(e) {WSH.StdOut.Write("\r失败:\n");}
}
function enlarge(file, m, n)
{
    var aso, txt;
    aso = new ActiveXObject("ADODB.Stream");
    aso.Mode = 3;
    aso.Type = 2;
    aso.Charset = "cp437";
    aso.Open();
    aso.LoadFromFile(file);
    txt = aso.ReadText(-1);
    if (txt.indexOf('\x00') > -1) {
        aso.Position = 0;
        aso.Charset = "unicode";
        txt = aso.ReadText(-1);
    }
    txt = txt.replace(/\\pos\((\d+),(\d+)(?=\))/g,
        function(s0,s1,s2){return "\\pos(" + s1*m + ',' + s2*n});
    aso.Position = 0;
    aso.WriteText(txt);
    aso.SetEOS();
    aso.SaveToFile(file + ".log", 2);
    aso.Close();
    aso = null;
    return txt;
}COPY
1

评分人数

TOP

本帖最后由 terse 于 2013-11-4 15:28 编辑

搞个PS练手
XP系统需安装有POWERSHELL win7自带无需另装
代码第一行 2.89 为设定数 自己修改
路径为 c:\test
对于编码的判断准确与否 没测试 运行请前先备份
$n=2.89
function Get-Encoding ($ph)
{
$ByteStr = Get-Content $Ph -Encoding Byte -TotalCount 3
$BOM = "{0:X}{1:X}{2:X}" -f $ByteStr
if ($BOM -eq "EFBBBF") { "UTF8" }
Else {
       $BOM = "{0:X}{1:X}" -f $ByteStr
       if ($BOM -eq "FFFE") { "Unicode" }
           Elseif ($BOM -eq "FEFF") {"BigEndianUnicode"}
           Else {"Ascii"}
       }
}
get-childitem "c:\te st\*" -include *.txt | ?{
$Encoding = Get-Encoding($_)
(Get-Content $_ | % {
    if ($_ -cmatch '(.+\\pos\()(\d+),(\d+)(.*)') {
       "$($matches[1])$([int]($n * $matches[2])),$([int]($n * $matches[3]))$($matches[4])"
    } else {"$_"}
}) | Set-Content  -Encoding $Encoding $_
}COPY

TOP

路径和文件扩展名 统一在前面定义
楼主没回复 浪费脑细胞
$n = 2.89
$Ph = "c:\test"
$Ext = "txt"
function Get-Encoding ($ph)
{
$ByteStr = Get-Content $Ph -Encoding Byte -TotalCount 3
$BOM = "{0:X}{1:X}{2:X}" -f $ByteStr
if ($BOM -eq "EFBBBF") { "UTF8" }
Else {
       $BOM = "{0:X}{1:X}" -f $ByteStr
       if ($BOM -eq "FFFE") { "Unicode" }
           Elseif ($BOM -eq "FEFF") {"BigEndianUnicode"}
           Else {"Ascii"}
       }
}
get-childitem "$Ph\*" -include *.$Ext | ?{
$Encoding = Get-Encoding($_)
(Get-Content $_ | % {
    if ($_ -cmatch '(.+\\pos\()(\d+),(\d+)(.*)') {
       "$($matches[1])$([int]($n * $matches[2])),$([int]($n * $matches[3]))$($matches[4])"
    } else {"$_"}
}) | Set-Content  -Encoding $Encoding $_
}COPY

TOP

返回列表