还是新的CMD批处理脚本…
我有一批从文件中删除制表符。 这通常用这个代码很好用:
setlocal DisableDelayedExpansion for /f "delims=" %%A in ('"findstr /n ^^ %FILENAME%"') do ( set "line=%%A" setlocal EnableDelayedExpansion set "line=!line:*:=!" if defined line ( set "line=!line: =!" (echo(!line!)>>%TEMPFILE% ) ELSE echo( endlocal )
但最近它并没有简单地删除制表符,而是整个行! 我认为它必须有一些不寻常的行长(> 9500个字符)。 如果我手动分割线,它照常工作。
现在我正在寻找一种方法
批处理文件中长行的问题是环境变量最多只能存储8 KB。 但是,可以用较小的块处理更长的行,因为当set /P
命令读取长行时,最多可读取1022个字符,其余字符将由下一个 set /P
命令读取。 下面的批处理文件使用这个方法(结合findstr /O "^"
,允许知道行的长度)复制一个文件与无限大小的行:
@echo off setlocal EnableDelayedExpansion set "last=1022" < input.txt ( for /F "delims=:" %%a in ('findstr /O "^" input.txt') do ( set /A "len=%%a-last-2, last=%%a, chunks=(len-1)/1022+1" set "chunk=" for /L %%i in (1,1,!chunks!) do ( set /P "chunk=" set /P "=!chunk!" < NUL ) if !chunks! gtr 0 echo/ ) for %%a in (input.txt) do set /A "len=%%~Za-last-2, chunks=(len-1)/1022+1" set "chunk=" for /L %%i in (1,1,!chunks!) do ( set /P "chunk=" set /P "=!chunk!" < NUL ) echo/ ) > output.txt move /Y output.txt input.txt
这种方法要求输入行以CR + LF字符结尾(Windows标准),并且存在set /P
固有的问题set /P
:它可以消除行尾或者每个块的末尾1022个字符的控制字符,或者从行/块开始的空格; 在这个职位的进一步细节。 你可以修改这个程序改变set /P "=!chunk!" < NUL
set /P "=!chunk!" < NUL
由相应的set /P "=!chunk: =!" < NUL
set /P "=!chunk: =!" < NUL
为了消除制表符。
cmd.exe
可以处理多达8k个字符的行。 我还需要处理更长的行,经过一番研究,我发现最简单的方法是使用外部程序。 我从UnxUtils使用sed
。
这个sed
命令应该删除所有的制表符:
sed -e "s/\t//g" <infile> > <outfile>
关于如何使用Windows命令行环境查找和替换文件中的文本? 描述几种使用控制台应用程序替换文件中字符串的方法。
Clay的实用工具for Win32的 xchange32是另一个控制台应用程序,它逐字节而不是逐行搜索文件的字节流,使得非常容易从文件中删除所有水平制表符,而不管是否存在行结束符。
与xchang32.exe一起使用的命令行适用于您的代码示例:
xchang32.exe "%FILENAME%" "^9" "">nul
要么
xchang32.exe "%FILENAME%" "^x09" "">nul
第一行指定十进制代码值9的水平制表符,而第二行使用十六进制代码值,这里的水平制表符也是9。
把xchang32.exe放到任何一个目录下,然后在完整路径的批处理文件中调用它。 使用该工具肯定比直到现在使用的批处理代码更快。
如果原始文件不能被xchang32.exe修改,请使用命令copy
先创建原始文件的副本,然后运行带有副本文件名的xchang32.exe 。
VBS理论行长度为20亿字节(或1×2 ^ 30个字符)。 你永远不会得到任何附近的地方(实际上是最大的自由连连内存块 – 它将是数百万字符)。
Set Arg = WScript.Arguments set WshShell = createObject("Wscript.Shell") Set Inp = WScript.Stdin Set Outp = Wscript.Stdout 'Remove ^ from quoting command line. Quote, ampersand and brackets Pttn = Replace(Arg(2), "^(", "(") Pttn = Replace(Pttn, "^)", ")") Pttn = Replace(Pttn, "^&", "&") Pttn = Replace(Pttn, "^""", """") Set regEx1 = New RegExp If Instr(LCase(Arg(1)), "i") > 0 then regEx1.IgnoreCase = True Else regEx1.IgnoreCase = False End If regEx1.Global = False regEx1.Pattern = Pttn Do Until Inp.AtEndOfStream Line=Inp.readline Line = RegEx1.Replace(Line, Arg(3)) outp.writeline Line Loop
如何使用。
更换
filter replace {i|n} expression replace filter repl {i|n} expression replace
使用正则表达式查找和替换文本。
也用于从文件中提取子字符串。
表达中的&符号和括号必须用脱字符号来逃脱。 不要脱口而出。 使用十六进制代码\ x22作为引号。
SearchOptions
i - ignore case n - none
表达
https://msdn.microsoft.com/en-us/library/ae5bf541(v%3Dvs.90).aspx
更换
要替换的文字。 使用$ 1,$ 2,$ …,$ n指定替换字符串中的子匹配
例
filter replace i "=" "No equal sign" < "%systemroot%\win.ini"
这将在方括号内搜索文本,并用括号中的文本替换后面的文本
Filter replace i "^\[^(.*^)\]" "cat$1" < %windir%\win.ini
这将搜索任何文本并从第11个字符打印到行尾。
Filter replace i "^.{10}^(.*^)$" "$1" < %windir%\win.ini
这将搜索CSV文件并打印第二个和第四个字段
Filter replace i "^.+,^(.+^),.+,^(.+^)$" "$1,$2" < csv.txt
过滤器只读标准和标准输出。 这些仅在命令提示符下可用。
filter <inputfile >outputfile filter <inputfile | other_command other_command | filter >outputfile other_command | filter | other_command
在这里下载完整的源代码https://skydrive.live.com/redir?resid=E2F0CE17A268A4FA!121