当前位置: 首页 > article >正文

PHP实现终端表格提取

背景

刚开始使用restic想要获取终端的输出数据,默认的终端信息如下示例

restic snapshots

repository 5816ba52 opened (version 2, compression level auto)
ID        Time                 Host        Tags        Paths       Size
-----------------------------------------------------------------------
753dd093  2024-11-22 12:04:57  kylinv10                /root/test  0 B
-----------------------------------------------------------------------
1 snapshots

希望得到的数据是表格转为数组

array(1) {
  [0]=>
  array(6) {
    ["ID"]=>
    string(8) "753dd093"
    ["Time"]=>
    string(19) "2024-11-22 12:04:57"
    ["Host"]=>
    string(8) "kylinv10"
    ["Tags"]=>
    string(0) ""
    ["Paths"]=>
    string(10) "/root/test"
    ["Size"]=>
    string(3) "0 B"
  }
}

提取遇到的问题:

1. 如果是简单的按空格分割,时间字段中间带有空格的,会被切成两段,如果表头有多个单词也可能出现分段;

2. 发现字段直接是按两个空格分隔, 可以考虑用两个空格作为分割符, 可是会遇到Tags列可能是空的,到时表头与行的列对不上

解决思路

1. 先将文本按行分割

2. 找到表头行,及表格内容行

3. 表头行通过双空格作为分割符分割,取得列名及其列宽

4. 按列名及列宽提取每个表格内容行

5. 组装数组

实现代码

 

<?php
// 给定的文本
$text = "repository 5816ba52 opened (version 2, compression level auto)
ID        Time                 Host        Tags        Paths       Size
-----------------------------------------------------------------------
753dd093  2024-11-22 12:04:57  kylinv10                /root/test  0 B
-----------------------------------------------------------------------
1 snapshots";

function keys($line)
{
    $items = explode('  ', $line);
    $end   = 0;
    $keys  = [];
    $width = [];
    foreach ($items as $n => $item) {
        if (strlen($item) == 0) {
            $end += 2;
            continue;
        }
        $keys[] = trim($item);
        if ($n > 0 and $items[$n - 1] == '') {
            $end += 2;
        }
        $width[] = $end;
        $end += strlen($item);
    }
    $width[] = $end;
    $res     = [];
    foreach ($keys as $n => $key) {
        $res[$key] = [$width[$n], $width[$n + 1]];
    }
    return $res;
}

function rowSplit($keys, $line)
{
    $res = [];
    foreach ($keys as $key => $step) {
        $res[$key] = trim(substr($line, $step[0], $step[1] - $step[0]));
    }
    return $res;
}

// 将字符串按行分割
$lines = explode("\n", $text);

$res = [];

$th   = [];
$tr   = [];
$pick = false;
foreach ($lines as $n => $line) {
    if (str_starts_with($line, '----')) {
        if ($pick) {
            break;
        }
        if (empty($th)) {
            $th   = keys($lines[$n - 1]);
            $pick = true;
            continue;
        }
    }
    if ($pick) {
        $tr    = rowSplit($th, $line);
        $res[] = $tr;
    }
}


// 打印结果
var_dump($res);

后记

后来深入了解restic后,发现传参--json就可以得到json输出了,以上的代码就不需要了,在此记录一下,留个痕:)


http://www.kler.cn/a/412480.html

相关文章:

  • [代码随想录Day24打卡] 93.复原IP地址 78.子集 90.子集II
  • 34 基于单片机的指纹打卡系统
  • docker如何安装redis
  • 4.STM32之通信接口《精讲》之IIC通信---软件实现IIC《深入浅出》面试必备!
  • 最新《软件工程》选择题及答案
  • 文件内容扫描工具
  • Three.js 和其他 WebGL 库 对比
  • Docker--将镜像推送到阿里云仓库中
  • linux上离线部署Mysql5.7.22
  • 5.1 MySQL 锁机制
  • 【pyspark学习从入门到精通22】机器学习库_5
  • 如何做小红书平台关键词优化??
  • springboot+vue电影购票系统(源码+文档+调试+答疑)
  • linux安全管理-会话安全
  • 计算机网络的初步认识
  • MyBatis的优缺点
  • 每日一题 LCR 109. 打开转盘锁
  • 【系统架构设计师】高分论文:论软件架构的生命周期
  • QT6学习第五天 第一个QT Quick程序
  • Web登录页面设计
  • 复合查询和内外连接
  • opengl 三角形
  • 【VIM编辑器】vim简单使用方法
  • 贪心-哈夫曼树——acwing
  • 【智能制造-45】汽车SE分析
  • TCP三次握手与四次挥手(TCP重传机制,2MSL)超详细!!!计算机网络