Batch file 需要替换1个非常长的文本文件行中的13个空格

Batch file 需要替换1个非常长的文本文件行中的13个空格,batch-file,cmd,str-replace,Batch File,Cmd,Str Replace,我有一个文件(1.8MB),其中有一行(很长)文本。该行上的值通常由13个空格分隔。我想做的是用管道分隔符替换这13个空格,这样我就可以使用SSIS处理这个文本文件 到目前为止,我还没有成功地使用批处理文件以编程方式处理这个文件 我已经尝试使用下面的代码,我从另一个SO帖子得到 @echo off REM create empty file: break>R1.txt setlocal enabledelayedexpansion REM prevent empty lines

我有一个文件(1.8MB),其中有一行(很长)文本。该行上的值通常由13个空格分隔。我想做的是用管道分隔符替换这13个空格,这样我就可以使用SSIS处理这个文本文件

到目前为止,我还没有成功地使用批处理文件以编程方式处理这个文件

我已经尝试使用下面的代码,我从另一个SO帖子得到

    @echo off 
REM create empty file:
break>R1.txt
setlocal enabledelayedexpansion
REM prevent empty lines by adding line numbers (find /v /n "")
REM parse the file, taking the second token (*, %%b) with delimiters
REM ] (to eliminate line numbers) and space (to eliminate leading spaces)
for /f "tokens=1,* delims=] " %%a in ('find /v /n "" ^<PXZP_SND_XZ01_GFT10553.dat') do (
  call :sub1 "%%b"
  REM write the string without quotes:
  REM removing the qoutes from the string would make the special chars poisonous again
  >>PXZP_SND_XZ01_GFT10553.dat echo(!s:"=!
)

REM Show the written file:
type PXZP_SND_XZ01_GFT10553.dat 
goto :eof

:sub1
set S=%*
REM do 13 times (adapt to your Needs):
for /l %%i in (1,1,13) do (
  REM replace "space qoute" with "quote" (= removing the last space
  set S=!S: "=|!
)
goto :eof
使用合适的工具

Set Inp = wscript.Stdin
Set Outp = wscript.Stdout
Outp.Write Replace(Inp.ReadAll, "             ", "|")
使用

cscript //nologo "C:\Replace13Spaces.vbs" < "c:\folder\inputfile.txt" > "C:\Folder\Outputfile.txt"
还有两种方法可以解决这个问题

  • 与第一种方法类似,第一种方法是从最长到最短的预定义空间数进行多次替换。即13、10、8或5个空格

  • Split
    2个空格上的钉住<代码>筛选要排除空白数组元素的数组。然后以
    |
    作为分隔符连接
    数组

  • 无法处理长度超过8190个字符的行。但是,有一种方法可以读取行较长的文件:在循环中使用
    set/P
    最多读取1023个字符,除非遇到换行符或文件结尾;对同一个打开(输入重定向)文件句柄执行多次,可以读取1023个字符中的非常长的行,因为
    set/P
    不会重置文件指针

    另一个挑战是返回(回显)很长的行,这在REACH中是不可能的,因为行限制约为8190个字符(适用于命令行和变量内容)。在这里,分块处理也有帮助:首先,获取文件结尾字符(EOF,ASCII 0x1A);然后获取文本/字符串部分,附加一个EOF,并使用
    echo
    (附加一个换行符)将结果写入一个临时文件,以及;接下来,使用将文件复制到自身上,但以ASCII文本模式读取该文件,以丢弃EOF和之后的所有内容(因此前面附加了
    echo
    )的换行符,并以二进制模式写入该文件,以获得结果数据的精确副本;最后,使用键入文件内容

    以下脚本使用了这些技术(请参阅代码中的所有解释性
    rem
    注释):

    @echo关闭
    setlocal EnableExtensions DisableDelayedexpansion
    rem//在此处定义常量:
    设置“\u INPUT=。\PXZP\u SND\u XZ01\u GFT10553.dat”&rem/(这是输入文件)
    设置“_OUTPUT=。\R1.txt”&rem//(设置为“con”在控制台上显示结果)
    设置“\u TEMPF=%TEMP%\%~n0\u%RANDOM%.tmp”&rem/(指定临时文件)
    设置“_SEARCH=“&rem/(这是要找到的字符串)
    设置“_REPLAC=|”&rem/(这是替换字符串)
    设置“_LTRIM=#”&rem/(设置为左修剪子字符串的某个值)
    (设置为左)=^
    %=空行=%
    )&rem//(此块在变量中存储新行字符)
    rem//这将在变量中存储文件结尾字符:
    对于/F%%E in('forfiles/P“%~dp0.”/M“%~nx0”/C“cmd/C echo 0x1A”),请设置“\u EOF=%%E”
    rem/*将在子程序中处理输入文件,
    rem通过输入重定向“%”“%\u OUTPUT%”调用访问文件内容:进程
    端部
    退出/B
    :进程
    rem//重置存储要处理的部分字符串和分隔符的变量:
    set“PART=”&set“SEP=”
    setlocal EnableDelayedExpansion
    :读
    rem/*此时从输入文件最多读取1023个字符,直到
    rem遇到换行或文件结尾:*/
    设置“NEW=”&set/P NEW=“”
    rem//读取的字符被附加到将被处理的字符串缓冲区:
    设置“零件=!零件!!新!”
    rem/*当字符串缓冲区为空时跳过处理,即结束时
    已到达文件的rem:*/
    :循环
    如果定义了零件(
    rem/*将搜索字符串作为中的` for`元变量引用进行访问
    rem不必使用正常(立即)`%`-扩展,这可能导致
    在某些情况下,某些特殊字符会出现rem故障:*/
    对于/F delims^=^eol^=%%K in(“!\u SEARCH!”)执行以下操作(
    rem/*尝试在第一个搜索字符串处拆分字符串缓冲区并存储
    右侧rem部分,使用子字符串替换:*/
    设置“右=!部分:%%K=!”
    rem/*检查拆分是否成功,从而检查是否存在搜索字符串
    rem甚至出现在字符串缓冲区中;如果没有,请跳回并读取更多内容
    rem字符;否则(当到达文件末尾时)清除
    rem右部分并继续处理:*/
    如果“!RIGHT!”==”!PART!(如果未定义新的)(设置“RIGHT=”)否则转到:读取
    rem/*清除将接收到第一个剩余部分的变量
    rem搜索字符串在字符串缓冲区中的出现;然后替换每个
    通过新行字符在字符串缓冲区中出现rem:*/
    set“LEFT=”&set^“PART=!PART:%%K=^%\u LF%%\u LF%!^”
    rem/*迭代更改的字符串缓冲区的所有行,该缓冲区现在是
    rem多行字符串,然后获取构成
    第一个搜索字符串左侧的rem部分;(第一)行为
    rem前面加了一个` `,只是为了不让它显示为空,因为` for/F`
    rem跳过空行;稍后将删除此字符:*/
    对于/F delims^=^eol^=%%L in(^“!PART!^”)do(
    rem//仅在第一次迭代中执行循环体:
    如果未定义,请单击“左”(
    rem/*存储延迟扩展的(扩展的)左侧部分
    rem已禁用,以免在字符串中出现“!”问题:*/
    setlocal DisableDelayedExpansion&设置“LEFT=%%L”
    rem//Ena
    
    cscript //nologo "C:\Replace13Spaces.vbs" < "c:\folder\inputfile.txt" > "C:\Folder\Outputfile.txt"
    
    Set Inp = wscript.Stdin
    Set Outp = wscript.Stdout
    Set regEx = New RegExp
    regEx.Pattern = "\s{2,}"
    regEx.IgnoreCase = True
    regEx.Global = True
    Outp.Write regEx.Replace(Inp.ReadAll, "|")