如果单词退出,则删除行并在powershell中打印具有两个单词的行之间的所有行
Posted
技术标签:
【中文标题】如果单词退出,则删除行并在powershell中打印具有两个单词的行之间的所有行【英文标题】:Removing lines if word exits and printing all lines between lines having two words in powershell 【发布时间】:2014-03-07 21:54:01 【问题描述】:问题一:
我有一个包含大约 2,000,000 行的 MAIN.txt 文件。文件将采用以下格式
单位=123 xxx 年年了
单位=245 xx 是的
单位=PO 789 x 是的
单位=258 xy 是的
单位=777 xz zx
单位=999 yz zy
单位=456 zz 是的
我想删除包含单词“PO”的行和后面的三行。
样本输出:
单位=123 xxx 年年了
单位=245 xx 是的
单位=258 xy 是的
单位=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 中做同样的事情。
【问题讨论】:
我试过了,但我只能删除带有 PO 的行 --> 请向我们展示你的代码! 看你的第二个问题的例子,我没有看到除数字以外的内容,所以我不确定要建议什么,尽管通过添加一些if
语句到我的另一个答案,你可能会到达那里......
【参考方案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 运行行检查功能之前将其清理为新文件。
【讨论】:
【参考方案2】:对于问题 #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
【讨论】:
以上是关于如果单词退出,则删除行并在powershell中打印具有两个单词的行之间的所有行的主要内容,如果未能解决你的问题,请参考以下文章
Pandas:删除缺少数据的行并在 UDF 中应用二进制编码
xcode swift:NSUserDefaults:如果退出应用程序,则保存高分并在停止的地方重新启动它