查找图案之间的线,并将第一条线追加到线

时间:2018-08-23 15:26:09

标签: powershell text-parsing

在以下情况下,我试图在Powershell中编写脚本。我已经在bash终端上使用Sed完成了此练习,但是在Powershell中编写时遇到了麻烦。任何帮助将不胜感激。
    ({sudo pip install -U colorama ,文件格式不包含sed -r -e '/^N/h;/^[N-]/d;G;s/(.*)\n(.*)/\2 \1/' <file><字符,每行的第一个字母周围)

开始模式始终以>开始(每个块仅1个实例),两行之间的行以<N>开始,结束模式始终为<J>

--

我正在尝试将每个部分-------------- <N>ABC123 <J>SomethingHere1 <J>SomethingHere2 <J>SomethingHere3 -------------- <-- end of section 中的第一行复制到同一部分中的每个<N>之后。例如:

<J>

每节<J>SomethingHere1 <N>ABC123 <J>SomethingHere2 <N>ABC123 <J>SomethingHere3 <N>ABC123 行的数量可以变化(0-N)。在没有<J>的情况下,无需执行任何操作。

Powershell版本:5.1.16299.611

1 个答案:

答案 0 :(得分:2)

以下基于管道的解决方案不快,但从概念上讲简单

Get-Content file.txt | ForEach-Object {
  if ($_ -match '^-+$') { $newSect = $true }
  elseif ($newSect) { $firstSectionLine = $_; $newSect = $False }
  else { "{0}`t{1}" -f $_, $firstSectionLine }
}
  • 它逐行读取和处理行(手头的行反映在自动变量$_中。

  • 它使用带有^-+运算符的正则表达式(-match)来标识节分隔符;如果找到,则标记$newSect设置为表示 next 行是该节的第一条数据线。

  • 如果第一个数据行被命中,它将被缓存在变量$firstSectionLine中,并且$newSect标志将被重置。

  • 根据定义,所有其他行都是第一条数据行将附加到的行,这是通过-f字符串格式运算符使用制表符char来完成的。 (`t作为分隔符。


这是一个更快的PSv4 +解决方案,它更复杂,但是它将整个输入文件读入内存

((Get-Content -Raw file.txt) -split '(?m)^-+(?:\r?\n)?' -ne '').ForEach({
  $firstLine, $otherLines = $_ -split '\r?\n' -ne ''
  foreach ($otherLine in $otherLines) { "{0}`t{1}" -f $otherLine, $firstLine }
})
  • Get-Content -Raw作为单个字符串完整读取输入文件。

  • 它使用-split运算符将输入文件分成多个部分,然后处理每个部分。

  • 正则表达式'(?m)^-+(?:\r?\n)?'与节分隔线匹配,可以选择后面跟换行符。

    • (?m)是多行选项,它使^$分别与每个的开头和结尾匹配:
    • \r?\n匹配换行符,格式为CRLF(\r\n)或仅LF(\n)格式。
    • (?:...)是一个非捕获组;使其不捕获可防止其匹配项包含在-split返回的元素中。
    • -ne ''过滤掉结果为空的元素。
  • -split '\r?\n'将每个部分分成几行。

如果仍然需要提高性能,则可以使用[IO.File]::ReadAllText("$PWD/file.txt")加快文件读取速度。