使用Powershell替换CRLF

16 浏览
0 Comments

使用Powershell替换CRLF

编辑注:根据OP后来的评论,这个问题的要点是:如何在PowerShell中将带有CRLF(Windows格式)行尾的文件转换为仅带有LF(Unix格式)行尾的文件?

以下是我的PowerShell脚本:

 $original_file ='C:\Users\abc\Desktop\File\abc.txt'
 (Get-Content $original_file) | Foreach-Object {
 $_ -replace "'", "2"`
-replace '2', '3'`
-replace '1', '7'`
-replace '9', ''`
-replace "`r`n",'`n'
} | Set-Content "C:\Users\abc\Desktop\File\abc.txt" -Force

使用这段代码,我可以将2替换为3,1替换为7,9替换为空字符串。但我无法将回车换行替换为仅有换行符。但这并没有起作用。

admin 更改状态以发布 2023年5月21日
0
0 Comments

您没有指定版本,我假设您正在使用 Powershell v3。

尝试这个:

$path = "C:\Users\abc\Desktop\File\abc.txt"
(Get-Content $path -Raw).Replace("`r`n","`n") | Set-Content $path -Force

编辑:正如Mike Z在评论中指出的那样,Set-Content 会附加一个不需要的结尾 CRLF。使用以下命令来验证:'hi' > t.txt; (Get-Content -Raw t.txt).Replace("`r`n","`n") | Set-Content t.txt; (Get-Content -Raw t.txt).EndsWith("`r`n"),结果为 $True

请注意,这会将整个文件加载到内存中,因此如果您要处理大型文件,则可能需要使用其他解决方案。

更新:

这可能适用于v2(很抱歉没有测试的地方):

$in = "C:\Users\abc\Desktop\File\abc.txt"
$out = "C:\Users\abc\Desktop\File\abc-out.txt"
(Get-Content $in) -join "`n" > $out

编辑:请注意,该解决方案现在将内容写入到不同的文件中,因此与(依然存在缺陷的)v3解决方案不相等。(使用 > 会在执行之前截断目标文件)。更重要的是,该解决方案也会附加一个不需要的结尾 CRLF。使用 'hi' > t.txt; (Get-Content t.txt) -join "`n" > t.NEW.txt; [io.file]::ReadAllText((Convert-Path t.NEW.txt)).endswith("`r`n") 来验证,结果为 $True

然而,同样需要注意该解决方案会将整个文件加载到内存中。

0
0 Comments

以下是截至 Windows PowerShell v5.1 / PowerShell Core v6.2.0 版本的最新答案:

  • Andrew Savinykh的回答 虽然曾经是被接受的最佳答案,但据本文撰写时刻,该答案存在根本缺陷(我希望这个问题会得到解决 - 在评论中有足够的信息 - 在编辑历史记录中也有)。

  • Ansgar Wiecher的回答 效果很好,但是需要直接使用 .NET Framework(并且将整个文件读入内存,尽管可以改变)。直接使用 .NET Framework本身不是问题,但对新手来说更难掌握,而且通常很难记住。

  • 未来版本的 PowerShell Core 可能会引入一个
    Convert-TextFile cmdlet,该命令将具有 -LineEnding 参数,以允许使用特定的换行符样式就地更新文本文件:请参见 GitHub问题#6201

PSv5+中,现在可以使用 PowerShell 原生解决方案,因为 Set-Content 现在支持 -NoNewline 开关,该开关可以防止不希望的追加平台本地换行符[1]:

# Convert CRLFs to LFs only.
# Note:
#  * (...) around Get-Content ensures that $file is read *in full*
#    up front, so that it is possible to write back the transformed content
#    to the same file.
#  * + "`n" ensures that the file has a *trailing LF*, which Unix platforms
#     expect.
((Get-Content $file) -join "`n") + "`n" | Set-Content -NoNewline $file

以上依赖于 Get-Content 能够逐行读取使用任何组合的 CR-only、CRLF 和 LF-only 换行符的文本文件的能力。

注意事项

  • 必须指定相同的输出编码来匹配输入文件,以便使用相同的编码重新创建文件。上面的命令未指定输出编码;要指定,请使用 -Encoding

  • 默认情况下,不使用 -Encoding

    • Windows PowerShell 中,您将获得"ANSI" 编码,即您系统的单字节、8位遗留编码,例如在美国英语系统上使用的 Windows-1252 编码。

    • PowerShell(Core)v6+中,您将获得没有BOM的UTF-8编码

    • 输入文件的内容以及其转换副本必须作为一个整体装入内存中,这可能会对大型输入文件造成问题,但对文本文件而言这很少是一个问题。

    • 如果写回到输入文件的过程被中断,存在文件损坏的小风险


[1]事实上,如果有多个字符串要写入,-NoNewline也不会在它们之间放置换行符;但是,在此情况下,这不重要,因为只写入一个字符串。

0