批处理文件,用于读取带有特殊字符的txt并替换其中的单词

时间:2016-10-10 13:46:43

标签: windows powershell batch-file

我正在尝试创建一个读取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

您可以在最后一行看到“hello”字样。我希望批处理进入流程并给我一个看起来像这样的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

你可以看到“你好”现在是“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中有一种方法可以做到这一点,我很高兴听到它。

3 个答案:

答案 0 :(得分:5)

你有什么看起来像一个二进制文件,而不是文本文件,尽管扩展。批处理不适合编辑二进制文件。在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)

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

答案 1 :(得分:1)

  

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

此批处理代码来自此site,并且指向discussion的链接为何不使用特殊字符。

答案 2 :(得分:0)

是的,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%"