2

似乎有类似的问题在网上流传,尽管答案各不相同,我只是无法得到我正在寻找的结果。

下面只是在文件末尾附加了txt文件中的内容

Add-Content -Path "HeartBeat.txt" -Value (Get-Content "insertme.txt")

虽然我想使用 powershell 在文本文件中查找字符串,然后在找到的字符串之后从另一个文本文件中复制内容。

搜索字符串“HeartBeat”的文本文件的虚构示例

<xml>
<Server>
  <HeartBeat>1</HeartBeat>
</Server>

还有另一个名为“insertme.txt”的文本文件,它将在“HeartBeat”之后的新行中插入其内容

<dummydata>
<port></port>
<ipaddress></ipaddress>

一旦附加将是

<xml>
<Server>
  <HeartBeat>1</HeartBeat>
  <dummydata>
  <port></port>
  <ipaddress></ipaddress>
</Server>

任何帮助,将不胜感激。

谢谢

4

1 回答 1

3

如果您想要一个真正强大的解决方案,请使用 PowerShell 通过[xml]( System.Xml.XmlDocument) .NET 类型支持的 XML 处理。

如果您仍然想要纯文本解决方案,请尝试以下操作(PSv3+;将两个文件全部读入内存;我在代码中使用仅 LF 换行符( );如果您想要 CRLF 换行符"`n",请将其替换为):"`r`n"

(Get-Content -Raw Heartbeat.txt) -replace
  '(?m)^.*<HeartBeat>.*$',
  ('$&' + "`n" + (Get-Content -Raw InsertMe.txt).TrimEnd() -replace '(?m)^', '  '))|
    Set-Content HeartBeat.txt # PSv5+: Add -NoNewline to avoid extra newline

注意:可以在单个管道中读取 Heartbeat.txt 和写回(...)它的唯一原因是,由于命令周围的原因,它的内容被预先完整地读入内存Get-Content
虽然这种方法很方便,但它也有轻微的数据丢失风险,如果管道在所有内容写回文件之前中断,可能会发生这种情况。

  • Get-Content -Raw将文件作为单个字符串完整读入内存。

  • 正则表达式'(?m)^.*<HeartBeat>.*$'匹配包含子字符串的单行<HeartBeat>(请注意,-replace运算符通常会查找多个匹配项)

  • 替换表达式'$&' + "`n" + (Get-Content -Raw InsertMe.txt).TrimEnd()用自身 ( $&) 替换匹配的行,后跟换行符和 file 的内容InsertMe.txt

    • .TrimEnd()用于删除尾随的换行符(和一般的空格),以便插入不会根据文件是否恰好以换行符结尾而变化。
  • 如果您想避免在更新文件末尾出现额外的换行符,请
    使用Set-Content -NoNewline,但请注意这需要 PSv5+。
    在早期版本中,您可以.TrimEnd()在将其发送到Set-Content.


如果要修改插入以对插入内容的每一行应用固定缩进

(Get-Content -Raw Heartbeat.txt) -replace
  '(?m)^.*<HeartBeat>.*$',
  ('$&' + "`n" + (Get-Content -Raw InsertMe.txt).TrimEnd() -replace '(?m)^', '  '))|
    Set-Content HeartBeat.txt # PSv5+: Add -NoNewline to avoid extra newline
于 2018-07-31T03:52:42.843 回答