如何保留 UNIX LF 行结尾?
How can I keep UNIX LF line endings?
我有一个大的 (9 GiB)、ASCII 编码、管道分隔的文件,带有 UNIX-style 行结尾; 0x0A.
我想将前 100 条记录抽样到一个文件中以供调查。以下将产生 100 条记录(1 header 条记录和 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 的任何信息。
如何生成具有 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"
)
-First 100
指示 Get-Content
读取(最多)100
行。
-ReadCount 100
导致这 100 行作为 数组 一起被读取和发出 ,从而加快读取和后续处理速度。
- 注意:在 PowerShell [Core] v7.0+ 中,您可以将 shorthand
-ReadCount 0
与 -First <n>
结合使用,表示:将请求的 <n>
行读取为单个数组;由于早期版本中的错误,包括 Windows PowerShell,-ReadCount 0
总是读取 整个 文件,即使存在 -First
(又名 -TotalCount
又名 -Head
).
此外,即使从 PowerShell [Core] 7.0.0-rc.2(撰写本文时的当前版本)开始,将 -ReadCount 0
与 -Last <n>
(又名 -Tail
) 应该避免(现在):虽然产生的输出是正确的,在幕后它又是整个文件被读取;参见 this GitHub issue。
注意 + "`n"
,它确保输出文件也有一个 trailing 换行符(Unix 世界中的文本文件是预计会有)。
虽然上面的方法也适用于 -Last <n>
(-Tail <n>
) 从文件的 end 中提取,Theo 的(较慢)Select-Object
解决方案在提取 任意范围 行方面提供了更大的灵活性,这要归功于可用参数 -Skip
、-SkipLast
和 -Index
;但是,在 this GitHub feature request.
中提议也 直接在 Get-Content
上提供这些参数以获得卓越的性能
另请注意,我使用了 Set-Content
而不是 Out-File
。
如果你知道你在写 text,Set-Content
就足够了,而且通常 faster (尽管在这种情况下这无关紧要,因为要写入的数据作为 单个 值传递)。
要全面了解 Set-Content
和 Out-File
/ >
之间的 差异,请参阅 this answer。
Set-Content
对比 Out-File
基准:
注意:此基准比较了两个 cmdlet 将通过管道 接收到的许多 输入字符串 写入文件。
# Sample array of 100,000 lines.
$arr = (, 'foooooooooooooooooooooo') * 1e5
# Time writing the array lines to a file, first with Set-Content, then
# with Out-File.
$file = [IO.Path]::GetTempFileName()
{ $arr | Set-Content -Encoding Ascii $file },
{ $arr | Out-File -Encoding Ascii $file } | % { (Measure-Command $_).TotalSeconds }
Remove-Item $file
使用 Windows PowerShell v5.1 的 Windows 10 VM 的示例计时(以秒为单位):
2.6637108 # Set-Content
5.1850954 # Out-File; took almost twice as long.
我有一个大的 (9 GiB)、ASCII 编码、管道分隔的文件,带有 UNIX-style 行结尾; 0x0A.
我想将前 100 条记录抽样到一个文件中以供调查。以下将产生 100 条记录(1 header 条记录和 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 的任何信息。
如何生成具有 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"
)
-First 100
指示Get-Content
读取(最多)100
行。-ReadCount 100
导致这 100 行作为 数组 一起被读取和发出 ,从而加快读取和后续处理速度。- 注意:在 PowerShell [Core] v7.0+ 中,您可以将 shorthand
-ReadCount 0
与-First <n>
结合使用,表示:将请求的<n>
行读取为单个数组;由于早期版本中的错误,包括 Windows PowerShell,-ReadCount 0
总是读取 整个 文件,即使存在-First
(又名-TotalCount
又名-Head
).
此外,即使从 PowerShell [Core] 7.0.0-rc.2(撰写本文时的当前版本)开始,将-ReadCount 0
与-Last <n>
(又名-Tail
) 应该避免(现在):虽然产生的输出是正确的,在幕后它又是整个文件被读取;参见 this GitHub issue。
- 注意:在 PowerShell [Core] v7.0+ 中,您可以将 shorthand
注意
+ "`n"
,它确保输出文件也有一个 trailing 换行符(Unix 世界中的文本文件是预计会有)。
虽然上面的方法也适用于 -Last <n>
(-Tail <n>
) 从文件的 end 中提取,Theo 的(较慢)Select-Object
解决方案在提取 任意范围 行方面提供了更大的灵活性,这要归功于可用参数 -Skip
、-SkipLast
和 -Index
;但是,在 this GitHub feature request.
Get-Content
上提供这些参数以获得卓越的性能
另请注意,我使用了 Set-Content
而不是 Out-File
。
如果你知道你在写 text,Set-Content
就足够了,而且通常 faster (尽管在这种情况下这无关紧要,因为要写入的数据作为 单个 值传递)。
要全面了解 Set-Content
和 Out-File
/ >
之间的 差异,请参阅 this answer。
Set-Content
对比 Out-File
基准:
注意:此基准比较了两个 cmdlet 将通过管道 接收到的许多 输入字符串 写入文件。
# Sample array of 100,000 lines.
$arr = (, 'foooooooooooooooooooooo') * 1e5
# Time writing the array lines to a file, first with Set-Content, then
# with Out-File.
$file = [IO.Path]::GetTempFileName()
{ $arr | Set-Content -Encoding Ascii $file },
{ $arr | Out-File -Encoding Ascii $file } | % { (Measure-Command $_).TotalSeconds }
Remove-Item $file
使用 Windows PowerShell v5.1 的 Windows 10 VM 的示例计时(以秒为单位):
2.6637108 # Set-Content
5.1850954 # Out-File; took almost twice as long.