在以下情况下,我试图在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
答案 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")
加快文件读取速度。