Batch file 需要替换1个非常长的文本文件行中的13个空格
我有一个文件(1.8MB),其中有一行(很长)文本。该行上的值通常由13个空格分隔。我想做的是用管道分隔符替换这13个空格,这样我就可以使用SSIS处理这个文本文件 到目前为止,我还没有成功地使用批处理文件以编程方式处理这个文件 我已经尝试使用下面的代码,我从另一个SO帖子得到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
@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"
还有两种方法可以解决这个问题
Split
2个空格上的钉住<代码>筛选要排除空白数组元素的数组。然后以|
作为分隔符连接数组
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, "|")