【问题标题】:Batch file to read a txt with special characters and replace a word in it批处理文件以读取带有特殊字符的 txt 并替换其中的单词
【发布时间】:2016-10-10 13:46:43
【问题描述】:

我正在尝试制作一个读取 txt 文件“ayylmao.txt”并找到特定单词“hello”并将其替换为“xello”的批处理文件。

问题是“ayylmao.txt”包含特定字符。

Ayylmao.txt 看起来像这样:

‹‹R‹Ę‹/M‹;Ču‹č˙˙˙‹‹@‰‹‹@CëC;Đu‹čq˙˙˙‹‹@C‹D$‰;7u®‹Ó‹Ćčúţ˙˙„Ŕu3Ŕ‰YZ]_^[ĂŤ@             SVWUÄđ‰$‹ô‹‰D$‹
‹‹@;Č‚†   ‹Ř‹>_‹ůz;ßrv;Ču!‹B‹A‹B‹)B‹x uV‹čđţ˙˙ëM‹Ř‹>_‹ůz;ßu
‹B‹)Bë3‹Z‰\$‹>‹‹.}+ű‰|$+Č‹‰HŤT$‹čMţ˙˙„Ŕu3 hello Ŕë°ë‹‹ ‰‹;D$…Y˙˙˙3ŔÄ]_^[ĂSVW‹Ú‹đţ   }ľ   ëĆ˙˙  ć  ˙˙‰sjh    Vj

你可以在最后一行看到“你好”这个词。我希望批次进入流程并给我一个 ayylmao1.txt,如下所示:

‹‹R‹Ę‹/M‹;Ču‹č˙˙˙‹‹@‰‹‹@CëC;Đu‹čq˙˙˙‹‹@C‹D$‰;7u®‹Ó‹Ćčúţ˙˙„Ŕu3Ŕ‰YZ]_^[ĂŤ@             SVWUÄđ‰$‹ô‹‰D$‹
‹‹@;Č‚†   ‹Ř‹>_‹ůz;ßrv;Ču!‹B‹A‹B‹)B‹x uV‹čđţ˙˙ëM‹Ř‹>_‹ůz;ßu
‹B‹)Bë3‹Z‰\$‹>‹‹.}+ű‰|$+Č‹‰HŤT$‹čMţ˙˙„Ŕu3 xello Ŕë°ë‹‹ ‰‹;D$…Y˙˙˙3ŔÄ]_^[ĂSVW‹Ú‹đţ   }ľ   ëĆ˙˙  ć  ˙˙‰sjh    Vj

您可以看到“hello”现在是“xello”。

我发现这个批处理文件可以替换文本文件中的一个单词:

@echo off
REM -- Prepare the Command Processor --
SETLOCAL ENABLEEXTENSIONS
SETLOCAL DISABLEDELAYEDEXPANSION

if "%~1"=="" findstr "^::" "%~f0"&GOTO:EOF
for /f "tokens=1,* delims=]" %%A in ('"type %3|find /n /v """') do (
    set "line=%%B"
    if defined line (
        call set "line=echo.%%line:%~1=%~2%%"
        for /f "delims=" %%X in ('"echo."%%line%%""') do %%~X
    ) ELSE echo.
)

此代码适用于没有特定字符的文件,如果像这样使用它:

code.bat "hello" "xello" "ayylmao.txt">"ayylmao1.txt"

此代码仅输入 ayylmao1.txt 几个特殊字符,但替换了 hello。我想要在那里输入所有的特殊字符。

我是这样设计的:

chcp 1252
code.bat "hello" "xello" "ayylmao.txt">"ayylmao1.txt"

但它没有用。它就像第一个代码一样工作。

如果 PowerShell 中有办法做到这一点,我会很高兴听到它。

【问题讨论】:

    标签: windows powershell batch-file


    【解决方案1】:

    尽管有扩展名,但您所拥有的看起来像是二进制文件,而不是文本文件。批处理不适合编辑二进制文件。在 PowerShell 中这是可行的,但您需要使用数据字节而不是简单文本。

    这是一个基本示例,它将在文件中查找字符串“hello”的第一次出现并将其替换为“xhello”:

    $f = 'C:\path\to\ayylmao.txt'
    
    $stext   = 'hello'
    $rtext   = [char[]]'xhello'
    
    $len    = $stext.Length
    $offset = $len - 1
    
    $data = [IO.File]::ReadAllBytes($f)
    
    # find first occurrence of $stext in byte array
    for ($i=0; $i -lt $data.Count - $offset; $i++) {
      $slice = $data[$i..($i+$offset)]
      if (-join [char[]]$slice -eq $stext) { break }
    }
    
    # Once you know the beginning ($i) and length ($len) of the array slice
    # containing $stext you can "cut up" $data and concatenate the slices before
    # and after $stext to the byte sequence you want to insert ($rtext):
    #
    #      |<--   $stext    -->|
    # [...]['h','e','l','l','o'][...]  <-- $data
    #    ^   ^               ^   ^
    #    |   |               |   |
    #    |   $i              |   $i+$len
    #    $i-1                $i+$offset (== $i+$len-1)
    #
    $rdata = $data[0..($i-1)] + [byte[]]$rtext + $data[($i+$len)..($data.Count-1)]
    
    [IO.File]::WriteAllBytes($f, $rdata)
    

    如果您希望替换以不同的方式工作,则需要调整此代码(也替换其他匹配项,替换其他匹配项,...)。

    【讨论】:

      【解决方案2】:

      但它没有用。它就像第一个代码一样工作。帮忙?

      此批处理代码来自此site,并且有一个指向discussion 的链接,为什么它不适用于特殊字符。

      【讨论】:

      • 这不适用于像 OP 那样的二进制文件。
      • @AnsgarWiechers 你是对的。我将编码类型修改为字节而不是 UTF8。
      • 将编码设置为 Byte 后,您将得到一个没有方法 Replace() 的字节数组。
      • @AnsgarWiechers 是的,你又是对的。哈哈。谢谢你的建议。我删除了我的 PowerShell 答案。我赞成你的,所以它显示为最佳答案。我留下了关于为什么批处理文件不起作用的第一个问题的网站链接的答案。
      • 您可能想总结该论坛的讨论,因此如果远程线程由于某种原因消失,您的回答仍然有效(并且有帮助)。
      【解决方案3】:

      是的,PowerShell replace 命令可以替换字符串并保留特殊字符。要从批处理脚本中调用它,请使用以下行

      powershell -command "(get-content Ayylmao.txt) -replace 'hello','xello' | set-content Ayylmao.txt"
      

      如果你想从命令行输入参数,那么该行将是

      powershell -command "(get-content %3) -replace '%1','%2' | set-content %4"
      

      如果您想使用批处理脚本中定义的变量,则与任何批处理脚本相同

      set file=Ayylmao.txt
      set Search_criteria=hello
      set Replace_criteria=xello
      powershell -command "(get-content %file%) -replace '%Search_criteria%','%Replace_criteria%' | set-content %file%"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多