我有一个MAIN.txt文件,包含2,000,000行。文件将采用以下格式
单元= 123
XXX
YYY单元= 245
XX
是的单位= PO 789
X
ÿ单元= 258
XY
yx单元777 =
XZ
zx单元= 999
YZ
zy单元= 456
ZZ
是的
我想删除包含“PO”字样的行以及跟随它们的三行。
示例输出:
单元= 123
XXX
yyy单元= 245
XX
YY单元= 258
XY
yx单元777 =
XZ
zx单元= 999
YZ
zy单元= 456
ZZ
是的
我是Powershell的新手。我尝试了这个,但我只能删除PO的行。如何删除后面的n行。
我有一个文件,比如extractthis.txt
-
123 | 258
777 | 456
我想在MAIN文件中打印出数字为123的行和258之后的两行(即bbb),并将其保存在一个新文件中,比如file1。
然后从extractthis.txt(777 | n456)读取第二行,并在具有数字777的行和具有456(jjj)的行之后的两行之间打印行,并将其保存到file2.txt,依此类推。
我在Unix中做过类似的事情。但我正在努力在Powershell中做同样的事情。
答案 0 :(得分:1)
对于问题#1,类似以下函数的东西应该可以工作(至少在我对你的数据文件进行尝试时它会这样做):
function Skip-Match {
[cmdletbinding()]
Param(
[parameter(Mandatory)][string]$Pattern,
[parameter(Mandatory)][string]$Path,
[int]$Count=3
)
$lines = Get-Content -Path $Path
$state = -1
$lines | ForEach-Object {
$line = $_
if( $line.ToString() -like "*$Pattern*" ) {
$state=3
} elseif ( $state -lt 0 ) {
$line
Write-Verbose $line
}
$state--
}
}
然后,您可以将其保存到文件(我称之为skip-match.ps1),获取文件,然后执行该功能......类似于:
. .\skip-match.ps1
Skip-Match -Pattern "PO" -Path .\datafile.dat
答案 1 :(得分:1)
鉴于你在MAIN.txt中有如此多的行,我会避免使用Get-Content,因为它会将整个文件打开到内存中。改用流。
function sanitise($file) {
$reader = [System.IO.File]::OpenText($file)
$i = 0
try {
while(($line = $reader.ReadLine()) -ne $null) {
if($i -gt 0) { $i++ }
if($i -gt 4) { $i = 0 }
if($line -like "*PO*") { $i++ }
if ($i -eq 0) { echo $line }
}
}
finally {
$reader.Close()
}
}
function readBetweenLines($file, $a, $b) {
$reader = [System.IO.File]::OpenText($file)
$i = 0
$read = $false
try {
while(($line = $reader.ReadLine()) -ne $null) {
if($i -gt 0) { $i++ }
if($line -match ".*$a`$") { $read = $true }
if($line -match ".*$b`$") { $i++ }
if(($read) -and ($i -lt 4)) { echo $line }
if($i -gt 4) { break }
}
}
finally {
$reader.Close()
}
}
sanitise(".\MAIN.txt")
$extract = get-content ".\extractthis.txt"
foreach($line in $extract) {
$lineNum = $line.split("|")
readBetweenLines ".\MAIN.txt" $lineNum[0] $lineNum[1]
}
将echo
语句替换为您在其他地方输出内容所需的任何内容。就目前而言,这还需要您在运行行检查功能之前将MAIN.txt清理为新文件。