为什么在 PowerShell 的 Get-Content、Regex 和 Set-Content 之后所有换行符都消失了? [英] Why are all newlines gone after PowerShell's Get-Content, Regex, and Set-Content?

查看:128
本文介绍了为什么在 PowerShell 的 Get-Content、Regex 和 Set-Content 之后所有换行符都消失了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将文件模板加载到变量中,修改变量内的数据并将修改后的模板从变量输出到新位置.

I want to load a file template into a variable, modify data within the variable and output the modified template to a new location from the variable.

问题是 PowerShell 正在从我的模板中删除换行符.

The issue is that PowerShell is removing newlines from my template.

输入文件(模板文件)有 Unix 行尾,输出也是必需的,因为修改版本的接收者是基于 Unix 的系统.

The input file (template file) has Unix line endings which are also required for output since the recipient of the modified version is a Unix-based system.

我有以下代码可以生成一个连接的单行代码:

I have the following code which results into a concatted one-liner:

[String] $replacement = "Foo Bar"
[String] $template = Get-Content -Path "$pwd\template.sh" -Encoding UTF8
$template = $template -replace '<REPLACE_ME>', $replacement
$template | Set-Content -Path "$pwd\script.sh" -Encoding UTF8

有模板输入:

#!/bin/sh
myvar="<REPLACE_ME>"
echo "my variable: $myvar"
exit 0

结果为:

#!/bin/sh myvar="Foo Bar" echo "my variable: $myvar" exit 0

在我看来,某处 LF 被一个简单的空格代替.最后在脚本的末尾添加了一个 CR LF,它在模板文件中不存在.

It appears to me that somewhere LF where replaced by one simple whitespace. Finally at the end of the script there is an added CR LF which was not present in the template file.

如何保留行尾并防止在最终脚本中进一步添加 (CR LF) 错误 行尾?

How do I preserve the line endings and prevent adding further (CR LF) wrong line endings to the final script?

推荐答案

对于 $replacement 变量,你真的不需要指定类型 [string], PowerShell 将从分配中推断出这一点.

For the $replacement variable, you don't really need to specify the type [string], PowerShell will infer that from the assignment.

对于$template 变量,[string] 实际上是错误的.默认情况下,Get-Content 会给你一个字符串数组(即行)而不是一个字符串.

For the $template variable, [string] is actually wrong. By default, Get-Content will give you an array of strings (i.e. lines) instead of one string.

但实际上,您甚至不想一开始就将输入分成几行.当 Set-ContentOut-File 看到一个数组作为他们的输入时,他们会用空格连接它.

But in fact you don't even want to split the input into lines in the first place. When Set-Content or Out-File see an array as their input, they will join it with spaces.

使用 -Raw 使 Get-Content 将整个文件作为一个字符串返回,这种方式也是行尾(如 Linux 的 LF文件)将保持原样.

Using -Raw makes Get-Content return the entire file as one string, this way also the line endings (like LF for Linux files) will stay the way they are.

$replacement = "Foo Bar"
$template = Get-Content -Path "$pwd\template.sh" -Encoding UTF8 -Raw
$template = $template -replace '<REPLACE_ME>', $replacement
Set-Content -Path "$pwd\script.sh" -Value $template -Encoding UTF8

PowerShell 将使用 BOM 保存所有 UTF-8 文件.如果您不想这样,则必须使用不同的实用程序来写入文件:

PowerShell will save all UTF-8 files with a BOM. If you don't want that, you must use a different utility to write the file:

$UTF8_NO_BOM = New-Object System.Text.UTF8Encoding $False

$replacement = "Foo Bar"
$template = Get-Content -Path "$pwd\template.sh" -Encoding UTF8 -Raw
$template = $template -replace '<REPLACE_ME>', $replacement
[System.IO.File]::WriteAllText("$pwd\script.sh", $template, $UTF8_NO_BOM)

注意事项:

  • PowerShell 运算符(如 -replace)对数组进行静默操作.$x -replace "search", "replacement" 将对 $x 的每个成员 执行替换操作,无论是单个字符串还是它们的数组.立>
  • 推荐阅读:PowerShell Set-Content和Out-File有什么区别?
  • PowerShell operators (like -replace) silently operate on arrays. $x -replace "search", "replacement" will perform a replace operation on every member of $x, be that a single string or an array of them.
  • Recommended reading: PowerShell Set-Content and Out-File what is the difference?

这篇关于为什么在 PowerShell 的 Get-Content、Regex 和 Set-Content 之后所有换行符都消失了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆