php来解析ps aux | grep ...结果

时间:2013-01-02 16:13:20

标签: php regex

我有一个系统脚本,它运行并将“ps aux | grep utilities”的结果传递给文本文件并选择文本文件,以便Web服务可以读取文件并在我的Web应用程序中显示结果。

以下是原始结果的示例:

user     12052  0.2  0.1 137184 13056 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust1 cron
user     12054  0.2  0.1 137184 13064 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust3 cron
user     12055  0.6  0.1 137844 14220 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust4 cron
user     12057  0.2  0.1 137184 13052 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust89 cron
user     12058  0.2  0.1 137184 13052 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust435 cron
user     12059  0.3  0.1 135112 13000 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust16 cron
root     12068  0.0  0.0 106088  1164 pts/1    S+   10:00   0:00 sh -c ps aux | grep utilities > /home/user/public_html/logs/dashboard/currentlyPosting.txt
root     12070  0.0  0.0 103240   828 pts/1    R+   10:00   0:00 grep utilities

由于我的php脚本解析了这个文本文件,我只需要提取以下内容(只是一个例子):

cust1
cust3
cust4
cust89
cust435
cust16

我尝试了许多不同的笨拙方式,似乎没有什么效果。我在下面列出的方式有效,但有时也会抓取垃圾,因为一行中“空格”的数量会随着爆炸而变化。

public function showProcesses() {
    $lines = file(DIR_LOGGER_ROOT . "dashboard/currentlyPosting.txt");
    $results = array();
    $i = 0;
    foreach($lines as $line) {
        if (preg_match("/php/i", $line)) {
            $userProcess = explode(" ", $line);
            if($userProcess[29] != "0:00" && strlen($userProcess[29]) < 20) {
                $results[$i] = $userProcess[29];
                $i++;
            }
        }
    }
    return $results;
}

有些人可以为此发布优雅的解决方案吗?我正在努力学习更好的做事方式,并希望得到指导。

3 个答案:

答案 0 :(得分:1)

您可以使用preg_split代替explode并在[ ]+(一个或多个空格)上拆分。但我想在这种情况下你可以选择preg_match_allcapturing

preg_match_all('/[ ]php[ ]+\S+[ ]+(\S+)/', $input, $matches);
$result = $matches[1];

模式匹配空格php,更多空格,非空格字符串(路径),更多空格,然后捕获下一个非空格字符串。第一个空间主要是为了确保您不将php与用户名的一部分匹配,而只是作为命令。

捕获的替代方法是PCRE的“保持”功能。如果您在模式中使用\K,则匹配中的所有内容都将被丢弃:

preg_match_all('/[ ]php[ ]+\S+[ ]+\K\S+/', $input, $matches);
$result = $matches[0];

答案 1 :(得分:0)

我会使用preg_match()。我为许多系统管理脚本做了类似的事情。这是一个例子:

$test = "user     12052  0.2  0.1 137184 13056 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust1 cron
user     12054  0.2  0.1 137184 13064 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust3 cron
user     12055  0.6  0.1 137844 14220 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust4 cron
user     12057  0.2  0.1 137184 13052 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust89 cron
user     12058  0.2  0.1 137184 13052 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust435 cron
user     12059  0.3  0.1 135112 13000 ?        Ss   10:00   0:00 php /home/user/public_html/utilities/runProcFile.php cust16 cron
root     12068  0.0  0.0 106088  1164 pts/1    S+   10:00   0:00 sh -c ps aux | grep utilities > /home/user/public_html/logs/dashboard/currentlyPosting.txt
root     12070  0.0  0.0 103240   828 pts/1    R+   10:00   0:00 grep utilities";

$lines = explode("\n", $test);

foreach($lines as $line){
        if(preg_match("/.php[\s+](cust[\d]+)[\s+]cron/i", $line, $matches)){
                print_r($matches);
        }

}

以上版画:

Array
(
    [0] => .php cust1 cron
    [1] => cust1
)
Array
(
    [0] => .php cust3 cron
    [1] => cust3
)
Array
(
    [0] => .php cust4 cron
    [1] => cust4
)
Array
(
    [0] => .php cust89 cron
    [1] => cust89
)
Array
(
    [0] => .php cust435 cron
    [1] => cust435
)
Array
(
    [0] => .php cust16 cron
    [1] => cust16
)

您可以将$test设置为等于exec的输出。您要查找的值将位于if下的foreach语句中。 $matches[1]将具有custx值。

答案 2 :(得分:0)

如果值之间的行中的空格数是可变的,则可以使用preg_split

你只需要改变:

$userProcess = explode(" ", $line);

为:

$userProcess = preg_split("#\s+#", $line);

\s+将匹配一个或多个空格,制表符或其他空白字符。

然后你可以得到倒数第二项:

$txt = $userProcess[count($userProcess) - 2];