对于 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 个字符,其余字符将由 next 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
固有的问题:它可能会从行尾或每个 1022 个字符块的末尾消除控制字符,或从行/块的开头开始的空格;更多详细信息请参见这篇文章。您可以修改此程序,将 set /P "=!chunk!" < NUL
更改为相应的 set /P "=!chunk: =!" < NUL
,以消除制表符。
cmd.exe
可以处理最多 8k 个字符的行。我还需要处理更长的行,经过一些研究,我发现最简单的方法是使用外部程序。我使用 UnxUtils中的
sed
。
此
sed
命令应删除所有制表符:
sed -e "s/\t//g" <infile> > <outfile>
VBS 理论行长度为 2,000,000,000 字节(或 1 x 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 进行引号。
搜索选项
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"
这会搜索方括号内的文本,并将该行替换为 cat 后跟方括号内的文本
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
在 PowerShell 中,鉴于 .NET 平台中有很多工具,因此有很多解决方案。
使用
$file = 'path\to\file'
中的文件名,我们可以将制表符 `t
替换为空字符串,然后保存到另一个文件,如下所示
(Get-Content $file -Raw).Replace("`t", "") > $outfile # or
(gc $file -Ra) -replace "`t" > $outfile
长度几乎为零,因为 .NET 中最长的字符串理论上可以达到 2GB
您也可以保存到同一个文件,但命令略有不同:
[IO.File]::WriteAllText($file, $([IO.File]::ReadAllText($file) -replace "`t"))
或
(Get-Content $file -Raw).Replace("`t", "") | Set-Content $file -Force # or
(gc $file -Ra).Replace("`t", "") | sc $file -Fo
这些会将整个文件读入内存并进行处理。对于大文件,您可能需要使用Replace CRLF using powershell中的缓冲解决方案。这样行和文件就可以无限长,没有任何限制
另请参阅