【问题标题】:Find lines between a pattern, and append 1st line to lines查找模式之间的行,并将第一行附加到行
【发布时间】:2019-01-30 00:53:33
【问题描述】:

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

开始模式总是以<N> 开头(每个块只有1 个实例),之间的行以<J> 开始,结束模式总是--

--------------
<N>ABC123
<J>SomethingHere1
<J>SomethingHere2
<J>SomethingHere3
--------------    <-- end of section

我正在尝试在每个部分 &lt;N&gt; 中取第一行,并在同一部分中的每个 &lt;J&gt; 之后复制它。例如:

<J>SomethingHere1    <N>ABC123
<J>SomethingHere2    <N>ABC123
<J>SomethingHere3    <N>ABC123

每个部分的&lt;J&gt; 行数可以变化 (0-N)。在没有&lt;J&gt; 的情况下,不需要做任何事情。

Powershell版本:5.1.16299.611

【问题讨论】:

    标签: powershell text-parsing


    【解决方案1】:

    以下基于管道的解决方案速度不快,但概念简单

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

    • 它使用正则表达式 (^-+) 和 -match 运算符来识别节分隔符;如果找到,则设置标志$newSect 以表示下一个 行是该部分的第一个数据行。

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

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


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

    ((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 运算符将输入文件分割成多个部分,然后处理每个部分。

    • Regex '(?m)^-+(?:\r?\n)?' 匹配节分隔线,可选地后跟换行符。

      • (?m) 是多行选项,它使^$ 分别匹配每个 的开始和结束:
      • \r?\n 匹配换行符,可以是 CRLF (\r\n) 或 LF-only (\n) 形式。
      • (?:...) 是非捕获组;使其不被捕获可防止匹配的内容包含在 -split 返回的元素中。
      • -ne '' 过滤掉产生的空元素。
    • -split '\r?\n' 将每个部分分成单独的行。

    如果性能仍然是一个问题,您可以使用[IO.File]::ReadAllText("$PWD/file.txt") 加快读取文件的速度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多