如何从powershell中的两个文本文件创建组合文件?
如何使用两个不同文本文件的组合行创建文件,并创建如下新文件:如何从powershell中的两个文本文件创建组合文件?,powershell,merge,file-io,interleave,Powershell,Merge,File Io,Interleave,如何使用两个不同文本文件的组合行创建文件,并创建如下新文件: First line from text file A First line from text file B Second line from text file A Second line from text file B ... 对于以下解决方案: 保持内存使用恒定(不提前将整个文件加载到内存中) 对较大的文件执行可接受的操作 需要直接使用.NET API: #输入文件,假定位于当前目录中。 #重要提示:调用.nET方法时
First line from text file A
First line from text file B
Second line from text file A
Second line from text file B
...
对于以下解决方案:
- 保持内存使用恒定(不提前将整个文件加载到内存中)
- 对较大的文件执行可接受的操作
#输入文件,假定位于当前目录中。
#重要提示:调用.nET方法时始终使用完整路径。
$dir=$PWD.ProviderPath
$fileA=[System.IO.File]::ReadLines(“dir/fileA.txt”)
$fileB=[System.IO.File]::ReadLines($dir/fileB.txt)
#创建输出文件。
$fileOut=[System.IO.File]::CreateText($dir/merged.txt)
#依次迭代文件的行,并写入每一对
#到输出文件。
而($fileA.MoveNext(),$fileB.MoveNext()-包含$true){
if($null-ne$fileA.Current){$fileOut.WriteLine($fileA.Current)}
if($null-ne$fileB.Current){$fileOut.WriteLine($fileB.Current)}
}
#打开(关闭)这些文件。
$fileA.Dispose()$fileB.Dispose()$fileOut.Dispose()
注意:.NET API默认使用UTF-8,但如果需要,您可以传递所需的编码
另请参见:相关的.NET API帮助主题:
仅使用PowerShell功能的解决方案:
- 注意:使用仅PowerShell功能,一次只能惰性地枚举一个文件的行,因此需要将另一个文件的行全部读取到内存中。
(但是,您可以再次通过.NET API使用惰性枚举,即:
,如上所示,或者将这两个文件完全提前读取到内存中。)System.IO.File]::ReadLines()
- 可接受性能的关键是只有一个调用(可能还有一个调用)处理所有输出行
- 但是,考虑到(没有
)本身速度相当慢,这是因为在读取的每一行中都添加了额外的属性,基于.NET API的解决方案的性能会显著提高-Raw
- 但是,考虑到(没有
-Encoding
参数。用于以下解决方案:
- 保持内存使用恒定(不提前将整个文件加载到内存中)
- 对较大的文件执行可接受的操作
#输入文件,假定位于当前目录中。
#重要提示:调用.nET方法时始终使用完整路径。
$dir=$PWD.ProviderPath
$fileA=[System.IO.File]::ReadLines(“dir/fileA.txt”)
$fileB=[System.IO.File]::ReadLines($dir/fileB.txt)
#创建输出文件。
$fileOut=[System.IO.File]::CreateText($dir/merged.txt)
#依次迭代文件的行,并写入每一对
#到输出文件。
而($fileA.MoveNext(),$fileB.MoveNext()-包含$true){
if($null-ne$fileA.Current){$fileOut.WriteLine($fileA.Current)}
if($null-ne$fileB.Current){$fileOut.WriteLine($fileB.Current)}
}
#打开(关闭)这些文件。
$fileA.Dispose()$fileB.Dispose()$fileOut.Dispose()
注意:.NET API默认使用UTF-8,但如果需要,您可以传递所需的编码
另请参见:相关的.NET API帮助主题:
仅使用PowerShell功能的解决方案:
- 注意:使用仅PowerShell功能,一次只能惰性地枚举一个文件的行,因此需要将另一个文件的行全部读取到内存中。
(但是,您可以再次通过.NET API使用惰性枚举,即:
,如上所示,或者将这两个文件完全提前读取到内存中。)System.IO.File]::ReadLines()
- 可接受性能的关键是只有一个调用(可能还有一个调用)处理所有输出行
- 但是,考虑到(没有
)本身速度相当慢,这是因为在读取的每一行中都添加了额外的属性,基于.NET API的解决方案的性能会显著提高-Raw
- 但是,考虑到(没有
注意:Windows PowerShell的cmdlet默认为“ANSI”编码,而PowerShell(核心)(v6+)使用无BOM的UTF-8;根据需要使用
-Encoding
参数。这是可行的,但有两个缺点:两个文件都先被完整地读入内存(尽管文本文件通常并不重要),写入输出文件的速度会非常慢,因为添加内容
必须在每次迭代中打开和关闭文件(通过在循环中只调用一个addcontent
调用,可以在一定程度上缓解此问题,但最好的解决方案是只调用一个Set Content
调用作为附加的管道段).两个小问题:$i
必须以0
开始,而不是1
开始。如果使用添加内容
,则应首先创建/截断输出文件。/cc@abrahamzinal此方法可行,但有两个缺点:两个文件都先完整读取到内存中(尽管文本文件通常并不重要)写入输出文件的速度会非常慢,因为添加内容
必须在每次迭代中打开和关闭文件(通过在循环中只进行一次添加内容
调用,可以在一定程度上缓解此问题,但最好的解决方案是仅将一次设置内容
调用作为附加管道段).两个小问题:$i
必须以0
开头,而不是1
。如果使用添加内容
,则应首先创建/截断输出文件。/cc@AbrahamZinala
$file1content = Get-Content -Path "IN_1.txt"
$file2content = Get-Content -Path "IN_2.txt"
$filesLenght =@($file1content.Length, $file2content.Length)
for ($i = 1; $i -le ($filesLenght | Measure-Object -Maximum).Maximum; $i++)
{ Add-Content -Path "OUT.txt" $file1content[$i]
Add-Content -Path "OUT.txt" $file2content[$i]
}
# Read the 2nd file into an array of lines up front.
# Note: -ReadCount 0 greatly speeds up reading, by returning
# the lines directly as a single array.
$fileBLines = Get-Content fileB.txt -ReadCount 0
$i = 0 # Initialize the index into array $fileBLines.
# Lazily enumerate the lines of file A.
Get-Content fileA.txt | ForEach-Object {
$_ # Output the line from file A.
# If file B hasn't run out of lines yet, output the corresponding file B line.
if ($i -lt $fileBLines.Count) { $fileBLines[$i++] }
} | Set-Content Merged.txt
# If file B still has lines left, append them now:
if ($i -lt $fileBLines.Count) {
Add-Content Merged.txt -Value $fileBLines[$i..($fileBLines.Count-1)]
}