gpt4 book ai didi

powershell - 使用批处理/powershell 脚本设置自定义行分隔符

转载 作者:行者123 更新时间:2023-12-03 11:19:32 24 4
gpt4 key购买 nike

我有一个大于 1.5GB 的大文件,它有 '#@#@#' 作为行分隔符。在通过 Informatica 处理它之前,我将用 CRLF 字符替换它。问题是,我在文件中有 CR ,LF 字符,我需要在替换之前删除它们。我找到了几个选项来做到这一点,但由于大小,我得到 OutofMemory 异常。

param
(
[string]$Source,
[string]$Destination
)

echo $Source
echo $Destination

$Writer = New-Object IO.StreamWriter $Destination
$Writer.Write( [String]::Join("", $(Get-Content $Source)) )
$Writer.Close()

我的问题是,无论如何将我的行分隔符设置为“#@#@#”,然后逐行读取文件以删除 CR、LF 字符。

最佳答案

好吧,我的第一次尝试慢得无法忍受。这是一个很好的解决方案,它能够在 2 分 48 秒内处理 1.8 GB 的文件:-)

我使用了混合批处理/JScript,因此它可以在 XP 以后的任何 Windows 机器上运行 - 不需要第 3 方 exe 文件,也不需要任何编译。

我读写 ~1 MB 的块。其实逻辑很简单。

我将所有\r\n 替换为一个空格,并将 #@#@# 替换为\r\n。您可以轻松更改代码中的字符串值以满足您的需要。

fixLines.bat

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment

::--- Batch section within JScript comment that calls the internal JScript ----
@echo off
setlocal disableDelayedExpansion

if "%~1" equ "" (
echo Error: missing input argument
exit /b 1
)
if "%~2" equ "" (
set "out=%~f1.new"
) else (
set "out=%~2"
)

<"%~1" >"%out%" cscript //nologo //E:JScript "%~f0"
if "%~2" equ "" move /y "%out%" "%~1" >nul

exit /b

----- End of JScript comment, beginning of normal JScript ------------------*/
var delim='#@#@#',
delimReplace='\r\n',
nl='\r\n',
nlReplace=' ',
pos=0,
str='';

var delimRegex=new RegExp(delim,"g"),
nlRegex=new RegExp(nl,"g");

while( !WScript.StdIn.AtEndOfStream ) {
str=str.substring(pos)+WScript.StdIn.Read(1000000);
pos=str.lastIndexOf(delim)
if (pos>=0) {
pos+=delim.length;
WScript.StdOut.Write(str.substring(0,pos).replace(nlRegex,nlReplace).replace(delimRegex,delimReplace));
} else {
pos=0
}
}
if (str.length>pos) WScript.StdOut.Write(str.substring(pos).replace(nlRegex,nlReplace));

修复 input.txt 并将输出写入 output.txt:
fixLines input.txt output.txt

覆盖原文件test.txt
fixLines test.txt

只是为了好玩,我尝试使用 JREPL.BAT 处理 1.8 GB 的文件。 .我不认为它会起作用,因为它必须将整个文件加载到内存中。计算机中安装了多少内存并不重要 - JScript 的最大字符串大小限制为 2GB。我认为还有其他限制在起作用。
jrepl "\r?\n:#@#@#" " :\r\n" /m /x /t : /f input.txt /o output.txt

命令失败并显示“内存不足”错误需要 5 分钟。然后我的电脑花了很长时间才从严重的内存滥用中恢复过来。

下面是我的原始自定义批处理/JScript 解决方案,一次读取和写入一个字符。

慢.bat
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment

::--- Batch section within JScript comment that calls the internal JScript ----
@echo off
setlocal disableDelayedExpansion

if "%~1" equ "" (
echo Error: missing input argument
exit /b 1
)
if "%~2" equ "" (
set "out=%~f1.new"
) else (
set "out=%~2"
)

<"%~1" >"%out%" cscript //nologo //E:JScript "%~f0"
if "%~2" equ "" move /y "%out%" "%~1" >nul

exit /b

----- End of JScript comment, beginning of normal JScript ------------------*/
var delim='#@#@#',
delimReplace='\r\n',
nlReplace=' ',
read=1,
write=2,
pos=0,
char;

while( !WScript.StdIn.AtEndOfStream ) {
chr=WScript.StdIn.Read(1);
if (chr==delim.charAt(pos)) {
if (++pos==delim.length) {
WScript.StdOut.Write(delimReplace);
pos=0;
}
} else {
if (pos) {
WScript.StdOut.Write(delim.substring(0,pos));
pos=0;
}
if (chr=='\n') {
WScript.StdOut.Write(nlReplace);
} else if (chr!='\r') {
WScript.StdOut.Write(chr);
}
}
}
if (pos) WScript.StdOut.Write(delim.substring(0,pos));

它奏效了,但它是一只狗。以下是处理 155 MB 文件的计时结果摘要:
slow.bat     3120 sec  (52 min)
jrepl.bat 55 sec
fixLines.bat 15 sec

我验证了所有三个解决方案都给出了相同的结果。

关于powershell - 使用批处理/powershell 脚本设置自定义行分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41267179/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com