powershell 检查TXT中的行是否满足条件,但“以高级方式”满足

m4pnthwp  于 2023-03-02  发布在  Shell
关注(0)|答案(2)|浏览(161)

我有一个1300兆字节的TXT文件(很大)。我想构建做两件事的代码:
1.每一行的开头都包含一个唯一的ID。如果满足该ID“组”的条件,我想检查所有具有相同唯一ID的行。(下面的答案是:对于具有唯一ID X的行,所有条件都已满足)
1.如果脚本完成了,我想从满足条件的TXT中删除所有行(见2),这样我就可以用另一个条件集重新运行脚本来“缩小”整个文档。
经过几个周期之后,我终于有了一组适用于文档中所有行的条件。看起来我目前的方法非常慢。(一个周期需要几个小时)。我的最终结果是一组适用于所有行代码的条件。如果你找到了更简单的方法,请随时推荐。欢迎提供帮助:)
到目前为止的代码(未填写1和2中的所有内容)

foreach ($item in $liste)
{
    
    # Check Conditions
    if ( ($item -like "*XXX*") -and ($item -like "*YYY*") -and ($item -notlike "*ZZZ*")) { 
        
     # Add a line to a document to see which lines match condition                    
        Add-Content "C:\Desktop\it_seems_to_match.txt" "$item"
        
    # Retrieve the unique ID from the line and feed array.                
        $array += $item.Split("/")[1]

    # Remove the line from final document
        $liste = $liste -replace $item, ""         
           
    
    }

                              
} 
# Pipe the "new cleaned" list somewhere
    $liste | Set-Content -Path "C:\NewListToWorkWith.txt"
# Show me the counts
    $array | group | % { $h = @{} } { $h[$_.Name] = $_.Count } { $h } | Out-File "C:\Desktop\count.txt"

演示行:
图片/字符串/2XXXXXXXX_rTTTTTw_GGGG1_顶部_MMM 1_YY 02_ZZZ 30_AAAA5.jpg图片/字符串/3XXXXXXXX_rTTTTTw_GGGG1_顶部_MMM 1_YY 02_ZZZ 30_AAAA5.jpg图片/字符串/4XXXXXXXX_rTTTw_GGGG1_顶部_MMM 1_YY 02_ZZ 30_AAAA5.jpg图片/字符串/5XXXXXXXXXX_rTTTw_GGGG1_顶部_MMM 1_YY 02_ZZ 30_AAAA5.jpg图片/字符串/5XXXXXXXXXX_rTTTw_GGGG1_顶部_MMM 1_YY 02_ZZ 30_AAAA5.jpg图片

83qze16e

83qze16e1#

性能注意事项:

  • Add-Content "C:\Desktop\it_seems_to_match.txt" "$item"

尽量避免 Package cmdlet管道
另请参阅:Mastering the (steppable) pipeline

  • $array += $item.Split("/")[1]

尽量避免使用递增赋值运算符(+=)来创建集合
另请参阅:Why should I avoid using the increase assignment operator (+=) to create a collection

  • $liste = $liste -replace $item, ""考虑到每次迭代都要重新分配(复制)一个很长的列表($liste),这是一个开销非常大的操作。

此外,更改当前正在迭代的数组也是一种不好的做法。

  • $array | group | ...

Group-Object是一个相当慢的cmdlet,您最好使用hashtable动态收集(或计数)项目(在此执行$array += $item.Split("/")[1]),如下所示:

$Name = $item.Split("/")[1]
if (!$HashTable.Contains($Name)) { $HashTable[$Name] = [Collections.Generic.List[String]]::new() }
$HashTable[$Name].Add($Item)
vaj7vani

vaj7vani2#

为了最小化内存使用,一次读取一行并检查它是否已经存在可能会更好。下面的代码我使用StringReader,你可以用StreamReader替换它来阅读文件。我正在检查整个字符串是否存在,但你可能想拆分该行。注意,我在输入中有重复项,但在字典中没有。见下面的代码:

$rows= @"
images/STRINGA/2XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGA/3XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGB/4XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGB/5XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGC/5XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGA/2XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGA/3XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGB/4XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGB/5XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
images/STRINGC/5XXXXXXXX_rTTTTw_GGGG1_Top_MMM1_YY02_ZZZ30_AAAA5.jpg
"@

$dict = [System.Collections.Generic.Dictionary[int, System.Collections.Generic.List[string]]]::new();
$reader = [System.IO.StringReader]::new($rows)
while(($row = $reader.ReadLine()) -ne $null)
{
   $hash = $row.GetHashCode()
   if($dict.ContainsKey($hash))
   {
      #check if list contains the string
      if($dict[$hash].Contains($row))
      {
         #string is a duplicate
      }
      else
      {
         #add string to dictionary value if it is not in list
         $list = $dict[$hash].Value
         $list.Add($row)
      }
   }
   else
   {
      #add new hash value to dictionary
      $list = [System.Collections.Generic.List[string]]::new();
      $list.Add($row)
      $dict.Add($hash, $list)
   }
}
$dict

相关问题