powershell从字符串后面的文本文件导入数据

时间:2018-07-31 03:17:28

标签: powershell full-text-search text-files string-operations

尽管答案各不相同,但我似乎无法获得想要的结果。

下面仅将内容附加到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>

任何帮助将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:3)

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

如果您仍然想要纯文本的解决方案,请尝试以下操作(PSv3 +;将两个文件全部读入内存;我在代码中使用仅LF换行符("`n");将其替换如果需要CRLF换行符,请使用"`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()用其自身($&)替换匹配的行,后跟换行符和文件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