如何从 powershell 中的两个文本文件创建组合文件?

How create combined file from two text files in powershell?

如何创建包含来自两个不同文本文件的组合行的文件,并创建像这样的新文件:

First line from text file A
First line from text file B
Second line from text file A
Second line from text file B
...
$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]
}

解决方案:

  • 保持内存使用不变(不会预先将整个文件加载到内存中)
  • 处理较大的文件时表现尚可。

需要直接使用.NET APIs:

# Input files, assumed to be in the current directory.
# Important: always use FULL paths when calling .nET methods.
$dir = $PWD.ProviderPath
$fileA = [System.IO.File]::ReadLines("dir/fileA.txt")
$fileB = [System.IO.File]::ReadLines("$dir/fileB.txt")

# Create the output file.
$fileOut = [System.IO.File]::CreateText("$dir/merged.txt")

# Iterate over the files' lines in tandem, and write each pair
# to the output file.
while ($fileA.MoveNext(), $fileB.MoveNext() -contains $true) {
  if ($null -ne $fileA.Current) { $fileOut.WriteLine($fileA.Current) }
  if ($null -ne $fileB.Current) { $fileOut.WriteLine($fileB.Current) }
}

# Dipose of (close) the files.
$fileA.Dispose(); $fileB.Dispose(); $fileOut.Dispose()

注意:.NET APIs 默认使用 UTF-8,但如果需要,您可以传递所需的编码。

另请参阅:相关的 .NET API 帮助主题:


仅使用 PowerShell 功能的解决方案:

  • 注意:使用仅限 PowerShell 的功能,您一次只能懒惰地枚举 一个 文件的行,因此需要将另一个完全读入内存。 (但是,您可以再次通过 .NET API 使用惰性枚举,即如上所示 System.IO.File]::ReadLines(),或者预先将 both 文件全部读入内存.)

  • 可接受性能的关键是只有 一个 Set-Content call (plus possibly one Add-Content 调用)处理 所有输出线。

    • 但是,考虑到 Get-Content(没有 -Raw)本身很慢,因为用附加属性装饰每一行读取,基于 .NET 的解决方案 APIs 的表现会明显更好.
# 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)]
}

注意:Windows PowerShellSet-Content cmdlet 默认为“ANSI”编码,而 PowerShell(核心) (v6+) 使用无 BOM 的 UTF-8;根据需要使用 -Encoding 参数。