使用Powershell替换CRLF
使用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替换为空字符串。但我无法将回车换行替换为仅有换行符。但这并没有起作用。
您没有指定版本,我假设您正在使用 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
。
然而,同样需要注意该解决方案会将整个文件加载到内存中。
以下是截至 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
也不会在它们之间放置换行符;但是,在此情况下,这不重要,因为只写入一个字符串。