批处理文件读取特殊字符的txt并替换它中的一个字
问题描述:
我想要制作一个批处理文件,它读取一个txt文件“ayylmao.txt”并找到一个特定的单词“hello”并将其替换为“ xello”。批处理文件读取特殊字符的txt并替换它中的一个字
事情是,“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
你可以看到“你好”现在是“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中有这样做的话,我很乐意听到它。
答
你有什么看起来像一个二进制文件,而不是文本文件,尽管扩展名。批处理编辑二进制文件并不好。在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)
你需要,如果你想调整这个代码替换的工作方式不同(也可以替换其他事件,替换不同的事件,......)。
这不适用于OP显然具有的二进制文件。 –
@AnsgarWiechers你是对的。我将编码类型修改为Byte而不是UTF8。 – paul543
将编码设置为Byte,您将得到一个没有方法Replace()的字节数组。 –