如何更改Powershell脚本,使其以ANSI-Windows-1252编码写出文件?

如何更改Powershell脚本,使其以ANSI-Windows-1252编码写出文件?,powershell,Powershell,我有一个银行应用程序脚本,它通过从每日输入银行文件中删除错误记录来生成“过滤”输出文件(请参阅)。“过滤”输出文件将被发送到状态以更新其系统。作为旁注,我们从银行收到的原始输入文件在我的文件编辑器(UltraEdit)中显示为Unix 1252(ANSI拉丁语1),并且每个记录仅以换行结束 我将从“干净”(无错误)和“脏”(包含4个错误)输入文件生成的两个测试输出文件发送到状态,以便在其端进行测试,以确保在实现之前一切正常,但有点担心,因为输出文件是以带有CRLF行结尾的UTF-16编码生成的,

我有一个银行应用程序脚本,它通过从每日输入银行文件中删除错误记录来生成“过滤”输出文件(请参阅)。“过滤”输出文件将被发送到状态以更新其系统。作为旁注,我们从银行收到的原始输入文件在我的文件编辑器(UltraEdit)中显示为Unix 1252(ANSI拉丁语1),并且每个记录仅以换行结束

我将从“干净”(无错误)和“脏”(包含4个错误)输入文件生成的两个测试输出文件发送到状态,以便在其端进行测试,以确保在实现之前一切正常,但有点担心,因为输出文件是以带有CRLF行结尾的UTF-16编码生成的,其中,输入和当前未滤波输出在Windows-1252中进行编码。此系统上的所有其他输出文件都是Windows-1252编码的

果不其然……我得到消息说,该州的系统编码不正确。他们的意见是: “文件编码为UCS-2 Little Endian,需要转换为ANSI才能在我们的系统上运行。这是出乎意料的

之后,没有详细事务的文件将通过我们的EFT rejects程序运行ok

看起来处理得还可以,但我们必须进行一些转换。它可以用ANSI发送,还是需要用UCS 2 Little Endian发送?”

我已尝试将–Encoding“Windows-1252”和–Encoding Windows-1252添加到我的out file语句中,但未成功,两者都返回消息: 输出文件:无法验证参数“Encoding”的参数。争论 “Windows-1252”不属于该集合 未知、字符串、unicode、双字节unicode、utf8、utf7、utf32、ascii、默认值、oem 由ValidateSet属性指定。提供集合中的参数 然后重试该命令。 在C:\EZTRIEVE\PwrShell\TEST2\u FilterR02.ps1:47 char:57 + ... OutputString |输出文件$OutputFileFiltered-编码“Windows-1252” + ~~~~~~~~~~~~~~ +CategoryInfo:InvalidData:(:)[Out File],ParameterBindingVal 异常 +FullyQualifiedErrorId:ParameterArgumentValidationError,Microsoft.Power Shell.Commands.OutFileCommand

这几天来,我一直在四处寻找帮助,但没有什么是真正清楚的,我发现的绝大多数都涉及从Windows-1252转换到另一种编码。昨天,我在stackoverflow上的某个地方找到一条评论,指出“ANSI”与Windows-1252相同,但到目前为止,我还没有找到任何说明如何将Windows-1252编码选项正确附加到out file语句中,以便Powershell接受它。我真的需要完成这个项目,这样我就可以处理下几个已经添加到我的队列。是否有可能我缺少的子参数需要附加到编码中

这是在运行Windows server 2016标准和Powershell 5.1的新备份服务器上的Dollar Universe(作业调度器)下测试的。我们的生产系统在Windows Server 2012 R2上运行Dollar Universe,也使用Powershell 5.1(是的,我们正在寻找一个足够的升级窗口:-)

在我上次尝试时,我的Powershell脚本是:

 [cmdletbinding()]
 Param
 (
     [string] $InputFilePath
 )   

 # Read the text file
 $InputFile = Get-Content $InputFilePath

# Initialize output record counter
$Inrecs = 0
$Outrecs = 0

# Get the time
$Time = Get-Date -Format "MM_dd_yy"

# Set up the output file name
$OutputFileFiltered = "C:\EZTRIEVE\CFIS\DATA\TEST_CFI_EFT_RETURN_FILTERED"

# Initialize the variable used to hold the output
$OutputStrings = @()

# Loop through each line in the file
# Check the line ahead for "R02" and add it to the output
# or skip it appropriately
for ($i = 0; $i -lt $InputFile.Length - 1; $i++)
{
    if ($InputFile[$i + 1] -notmatch "R02")
    {
        # The next record does not contain "R02", increment count and add it to the output
        $Outrecs++
        $OutputStrings += $InputFile[$i]
    }
    else
    {
        # The next record does contain "R02", skip it
        $i++
    }
}

# Add the trailer record to the output
$OutputString += $InputFile[$InputFile.Length - 1]

# Write the output to a file
# $OutputStrings | Out-File $OutputFileFiltered
$OutputStrings | Out-File $OutputFileFiltered -Encoding windows-1252

# Display record processing stats:

$Filtered = $Outrecs-$i

Write-Host $i  Input records processed

Write-Host $Filtered  Error records filtered out

Write-Host $Outrecs  Output records written
注:

  • 稍后,您澄清了需要LF(Unix样式)换行符-请参阅底部部分

  • 下一节将处理最初提出的问题,并介绍导致文件带有CRLF(Windows样式)换行符(在Windows上运行时)的解决方案


如果您的系统(也称为系统区域设置)恰好具有活动的ANSI代码页(例如,在美国英语或西欧系统上),请使用
-编码默认值
,因为
默认值
指Windows PowerShell中的该代码页
(但不在PowerShell Core中,它默认为无BOM的UTF-8,不支持
默认编码标识符)

验证方法:
(获取ItemPropertyValue HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage ACP)-eq“1252”

... | Out-File -Encoding Default $file
注:

  • 如果您确定数据实际上完全由ASCII范围字符(代码点位于7位范围内的字符,不包括重音字符,如
    )组成,
    -编码默认值
    将起作用,即使您的系统区域设置使用除Windows-1252以外的ANSI代码页,因为所有(单字节)ANSI代码页在其7位子范围内共享所有ASCII字符;然后您也可以使用
    -编码ASCII
    ,但请注意,如果毕竟存在非ASCII字符,它们将被转换为文字
    字符,从而导致信息丢失

  • Set Content
    cmdlet实际上默认为Windows PowerShell中的
    Default
    编码(但不是PowerShell核心,其中一致的默认值是不带BOM的UTF-8)

  • 虽然
    设置内容
    的字符串化行为不同于
    输出文件
    ——但如果要写入文件的对象已经是字符串,则实际上是更好的选择


否则,您有两个选项:

  • 直接使用.NET Framework文件I/O功能,您可以使用.NET支持的任何编码;例如:

      $lines = ...  # array of strings (to become lines in a file)
      # CAVEAT: Be sure to specify an *absolute file path* in $file,
      #         because .NET typically has a different working dir.
      [IO.File]::WriteAllLines($file, $lines, [Text.Encoding]::GetEncoding(1252))
    
  • 使用PowerShell Core,它允许您将任何支持的.NET编码传递给
    -encoding
    参数:

      ... | Out-File -Encoding ([Text.Encoding]::GetEncoding(1252)) $file
    

请注意,在PSv5.1+中,您实际上可以更改
>
>
运算符所使用的编码,如中所述。
但是,在Windows PowerShell中,您再次受到
Ou支持的编码的限制
$lines = ...  # array of strings (to become lines in a file)

($lines -join "`n") + "`n" | Set-Content -NoNewline $file
-Encoding ([Text.Encoding]::GetEncoding([int] (Get-ItemPropertyValue HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage ACP)))
$lines = ...  # array of strings (to become lines in a file)


# CAVEAT: Be sure to specify an *absolute file path* in $file,
#         because .NET typically has a different working dir.
[IO.File]::WriteAllText($file, ($lines -join "`n") + "`n")
([Text.Encoding]::GetEncoding([int] (Get-ItemPropertyValue HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage ACP)))