Powershell 如何保留UNIX LF行结尾?

Powershell 如何保留UNIX LF行结尾?,powershell,newline,line-endings,Powershell,Newline,Line Endings,我有一个大的(9Gib),ASCII编码,管道分隔的文件,带有UNIX风格的行结尾;0x0A 我想把前100条记录取样存档,以便调查。下面将生成100条记录(1条标题记录和99条数据记录)。但是,它将行结尾更改为DOS/Winodws样式;CRLF,0x0D0A Get-Content -Path .\wellmed_hce_elig_20191223.txt | Select-Object -first 100 | Out-File -FilePath .\elig.txt -

我有一个大的(9Gib),ASCII编码,管道分隔的文件,带有UNIX风格的行结尾;0x0A

我想把前100条记录取样存档,以便调查。下面将生成100条记录(1条标题记录和99条数据记录)。但是,它将行结尾更改为DOS/Winodws样式;CRLF,0x0D0A

Get-Content -Path .\wellmed_hce_elig_20191223.txt |
    Select-Object -first 100 |
    Out-File -FilePath .\elig.txt -Encoding ascii
我知道iconv、recode和dos2unix。这些程序不在我的系统上,不允许安装。我已经搜索并找到了很多去CRLF的地方。我没有发现任何关于去或保持自我的东西


如何生成具有LF行结尾而不是CRLF的文件?

您可以将Get-Content cmdlet中的行与Unix“`n”新行连接起来并保存该行

差不多

((Get-Content -Path .\wellmed_hce_elig_20191223.txt | 
        Select-Object -first 100) -join "`n") |
        Out-File -FilePath .\elig.txt -Encoding ascii -NoNewLine
要使用基于很少使用的
-ReadCount
参数的性能优化来补充:

Set-Content -NoNewLine -Encoding ascii .\outfile.txt -Value (
  (Get-Content -First 100 -ReadCount 100 .\file.txt) -join "`n") + "`n"
)
  • -前100行
    指示读取(最多)
    100行

  • -ReadCount 100
    使这100行作为数组一次读取和发出,从而加快读取和后续处理

    • 注意:在PowerShell[Core]v7.0+中,您可以将速记
      -ReadCount 0
      -First
      结合使用,意思是:将请求的
      行作为单个数组读取;由于早期版本(包括Windows PowerShell)中存在错误,
      -ReadCount 0
      始终读取整个文件,即使存在
      -First
      (aka
      -TotalCount
      aka
      -Head
      )。
      此外,即使在PowerShell[Core]7.0.0-rc.2(本文撰写之时的当前版本)中,也应避免将
      -ReadCount 0
      -Last
      (又名
      -Tail
      )相结合(目前):虽然生成的输出是正确的,但在幕后读取的还是整个文件;看
  • 注意
    +“`n”
    ,它确保输出文件也有一个尾随的换行符(Unix世界中的文本文件应该有)

虽然上述方法也可以使用
-Last
-Tail
)从文件末尾提取,但Theo的(较慢的)
选择对象
解决方案在提取任意范围的行方面提供了更大的灵活性,这要感谢可用的参数
-Skip
-SkipLast
,以及
-Index
;然而,为了获得更高的性能,在中建议直接在
获取内容
上提供这些参数

还请注意,我使用了
设置内容
而不是
输出文件

如果您知道自己正在编写文本,
设置内容就足够了,而且通常速度更快(不过在这种情况下,这并不重要,因为要写入的数据是作为单个值传递的)

有关
设置内容
输出文件
/
之间差异的全面概述,请参阅


设置内容
输出文件
基准:

注意:此基准测试比较了两个cmdlet将通过管道接收的许多输入字符串写入文件的情况

#100000行的样本数组。
$arr=(,'fooooooooooooo')*1e5
#将数组行写入文件的时间,首先使用设置的内容,然后
#没有文件。
$file=[IO.Path]::GetTempFileName()
{$arr |设置内容-编码Ascii$file},
{$arr | Out File-编码Ascii$File}|%{(度量命令$|).TotalSeconds}
删除项目$file
使用Windows PowerShell v5.1的Windows 10虚拟机的计时示例(秒):

2.6637108 # Set-Content
5.1850954 # Out-File; took almost twice as long.

除了最后一条记录没有LF之外,它工作得很好。我将我的修改为使用
-join“`n”)+“`n”|
,并且它按预期工作。看起来像[environment]::newline控制它,但它是只读的。您始终可以使用不同的操作系统或WSL。