【问题标题】:Match select-string of > 11 characters and also starting after a certain point in file匹配 > 11 个字符的选择字符串,并且在文件中的某个点之后开始
【发布时间】:2016-02-05 10:11:38
【问题描述】:

我想在文件 (std_serverX.out) 中搜索 11 个字符或更大的字符串 cpu= 值。此文件可以包含最多或超过 100 万行。

为了进一步限制搜索,我希望在找到字符串 Java Thread Dump 的第一次出现后开始搜索 cpu=。 在我的源文件中,字符串 Java Thread Dump 直到文件 1057465 行长的大约第 # 1013169 行才开始,因此Java Thread Dump 之前的 96% 是不必要的..

这是我要搜索的文件部分:

cpu=191362359.38 [reset 191362359.38] ms elapsed=1288865.05 [reset 1288865.05] s allocated=86688238148864 B (78.84 TB) [reset 86688238148864 B (78.84 TB)] defined_classes=468 
io= file i/o: 588014/275091 B, net i/o: 36449/41265 B, files opened:19, socks opened:0 [reset file i/o: 588014/275091 B, net i/o: 36449/41265 B, files opened:19, socks opened:0 ] 
user="Guest" application="JavaEE/ResetPassword" tid=0x0000000047a8b000 nid=0x1b10 / 6928 runnable [_thread_blocked (_call_back), stack(0x0000000070de0000,0x0000000070fe0000)] [0x0000000070fdd000] java.lang.Thread.State: RUNNABLE

如上,您可以看到 cpu=191362359.38 的长度为 12 个字符(包括句号和 2 个小数位)。如何匹配它以使小于 11 个字符的 cpu= 值被忽略而不打印到文件中?

这是我目前所拥有的:

Get-Content -Path .\std_server*.out | Select-String '(cpu=)' | out-File  -width 1024 .\output.txt

我已将我的命令精简到绝对基础,因此我不会被其他搜索要求弄糊涂。

另外,如果可能的话,我希望这个命令尽可能基本,以便它可以在 Powershell 的一个命令行中运行。所以没有高级脚本或定义的变量,如果我们可以避免的话...... :)

这与我打开的 previous message 有关,由于我没有准确定义我的要求而变得复杂。

提前感谢您的帮助。

安托因

【问题讨论】:

    标签: powershell select-string


    【解决方案1】:

    正则表达式查找 9 位数字,后跟文字 .,后跟 1 位或更多位数字。一行一行

    Get-Content -Path .\std_server*.out | 
     Select-String -Pattern 'cpu=\d{9}\.\d+' -AllMatches | 
      Select-Object -ExpandProperty matches  | 
        Select-Object -ExpandProperty value
    

    【讨论】:

    • 嗨,卡兰。感谢您的输入。这个逻辑有效:)
    【解决方案2】:

    当然可以,但是管道一百万行,你知道前 96% 没有相关性不会很快/高效。

    更快的方法是使用StreamReader 并跳过这些行直到找到Java Thread Dump 字符串:

    $CPULines = @()
    
    foreach($file in Get-Item .\std_server*.out)
    {
    
        # Create stream reader from file
        $Reader = New-Object -TypeName 'System.IO.StreamReader' -ArgumentList $file.FullName
        $JTDFound = $false
    
        # Read file line by line
        while(($line = $Reader.ReadLine()))
        {
            # Keep looking until 'Java Thread Dump' is found 
            if(-not $JTDFound)
            {
                $JTDFound = $line.Contains('Java Thread Dump')
            }
            else
            {
                # Then, if a value matching your description is found, add that line to our results
                if($line -match '^cpu=([\d\.]{11,})\s')
                {
                    $CPULines += $line
                }
            }
        }
    
        # dispose of the stream reader
        $Reader.Dispose()
    }
    
    # Write output to file
    $CPULines |Out-File .\output.txt
    

    【讨论】:

    • 嗨,马蒂亚斯。这很慢,我承认:) 不幸的是,当我尝试运行你的逻辑时,我打印出一个空白文件:( executionpolicy = RemoteSigned。将其保存为 ps1 文件并在 PS 中启动它为:&“目录名\分析CPU.ps1"
    • 而且您绝对确定字符串Java Thread Dump(完全一样)在文件中的一行中找到,在出现 cpu=... 之前?
    • 这是它在文件中的显示方式。 ==================================================== ============================== Java 线程转储:2016 年 1 月 25 日星期一 11:20:06 ======= ==================================================== ========================
    猜你喜欢
    • 1970-01-01
    • 2015-12-04
    • 1970-01-01
    • 2018-06-30
    • 2016-08-05
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多