如何使用PowerShell替换换行符?

57

给定包含以下内容的test.txt:

test
message

我希望最终得到的结果是:

testing
a message

我认为以下内容应该是可行的,但实际上并不可行:

Get-Content test.txt |% {$_-replace "t`r`n", "ting`r`na "}

我该如何进行查找和替换,其中要查找的内容包含CRLF?


对于以后阅读此文的任何人来说,% 是 ForEach-Object 的别名。 - GaTechThomas
6个回答

48

CRLF是两个字符,即CR和LF。然而,`n包含了两者。例如:

PS C:\> $x = "Hello
>> World"

PS C:\> $x
Hello
World
PS C:\> $x.contains("`n")
True
PS C:\> $x.contains("`r")
False
PS C:\> $x.replace("o`nW","o There`nThe W")
Hello There
The World
PS C:\>

我认为你在使用`r时遇到了问题。通过从你的示例中删除`r,仅使用`n,我成功解决了问题。当然,我不知道你是如何生成原始字符串的,所以我不知道里面有什么内容。


2
这个答案完全误导人,至少在现在是这样的(不知道14年后是否有所改变)。\n实际上代表一个单一字符,换行符。它并不包含两者!OP代码的问题在于,正如Peter Seale所回答的那样,GC会将文件内容以字符串数组的形式提供给你,其中每个条目都是一行。如果您需要匹配多行内容,则需要先使用-join "`r`n"`连接数组。 - Teejay
1
是的,\n代表的是\n,而不是\r\n`。 - codaamok

31
在我的理解中,Get-Content 在将文本文件经过管道处理时会消除所有的换行符和回车符。如果想要进行多行正则表达式匹配,需要将字符串数组重新组合成一个巨大的字符串。我通常会执行以下操作:
$text = [string]::Join("`n", (Get-Content test.txt))
[regex]::Replace($text, "t`n", "ting`na ", "Singleline")

澄清:仅适用于小文件!请勿尝试在40 GB日志文件上执行此操作 :)

感谢您的解释,给您点个赞。 - Jaroslav Záruba

26

使用 -Raw,您应该得到预期的结果


3
值得注意的是,这在PS v2中不可用,但如果将其导向Out-String,则会获得相同的效果。 - Robin
4
我猜测这个参数是用来弥补命令的无法原谅的粗鲁行为的,因为它返回了除本应有的结果以外的内容。对此给予加分。我之前不知道这一点,浪费了1小时来弄清楚为什么我的字符串缺少换行符。 - ekkis
2
请您能分享个例子吗?我找不到它。 - Sagar S.
在哪些情况下应该使用-Raw? - GaTechThomas

6
如果您想删除所有换行符并用某个字符(比如逗号)替换它们,则可以使用以下方法。
(Get-Content test.txt) -join ","

这种方法有效是因为Get-Content返回行数组。你可以将其视为许多语言中可用的标记化函数。

1
你可以在 powershell 中使用 "\\r\\n" 来表示新行。我在 servicenow 工具中使用了这种方式。
在我的情况下,"\r\n" 无法正常工作,所以我尝试使用 "\\r\\n",因为在 powershell 中,"\" 是转义字符。

等待,PowerShell 与 ServiceNow 结合使用?这是什么用例? - Vaisakh K M

0

您可以使用这个简单的Powershell指令来检测文件是否为CRLF格式

(cat -Raw $args) -match "\r\n$"

替换 \n 为 \r\n 是棘手的,因为您必须先检测它并仅在需要时应用替换,否则会很混乱。太复杂了。

无论如何,您可以忘记检测,在 PowerShell 中确保文件为 CRLF,无论原始类型如何,您可以执行以下操作:

cat $file > $file

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接