是否可以删除太长的行中的字符?如果没有,如何检查排长队?

问题描述 投票:0回答:4

对于 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 个字符)有关。如果我手动分割线,它会照常工作。

现在我正在寻找一种方法

  1. 使上面的代码适用于任何行长度或
  2. 插入对处理时间太长的行的检查,以便批处理可以停止进程并显示适当的消息。
windows batch-file cmd
4个回答
3
投票

批处理文件中长行的问题是环境变量最多只能存储 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
,以消除制表符。


1
投票

cmd.exe
可以处理最多 8k 个字符的行。我还需要处理更长的行,经过一些研究,我发现最简单的方法是使用外部程序。我使用
UnxUtils
中的 sed

sed
命令应删除所有制表符:

sed -e "s/\t//g" <infile> > <outfile>

0
投票

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


0
投票

在 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中的缓冲解决方案。这样行和文件就可以无限长,没有任何限制

另请参阅

© www.soinside.com 2019 - 2024. All rights reserved.