CSV文件到具有具体化路径的平面数组


CSV file to flat array with materialized path

我有CSV文件,其中包含文件和目录列表:

Depth;Directory;
0;bin
1;basename
1;bash
1;cat
1;cgclassify
1;cgcreate
0;etc
1;aliases
1;audit
2;auditd.conf
2;audit.rules
0;home
....

每一行取决于上面的一行(对于深度参数)

我想创建一个像这样的数组,以便将其存储到带有Materialized Paths 的MongoDB集合中

$directories = array(
  array('_id' => null,
        'name' => "auditd.conf",
        'path' => "etc,audit,auditd.conf"),
  array(....)
);

我不知道如何处理。。。有什么想法吗?

编辑1:我并不是真的在处理目录——这只是一个例子,所以我不能使用FileSystems函数或FileIterator。

编辑2:通过这个CSV文件,我可以创建一个JSON嵌套数组:

function nestedarray($row){
    list($id, $depth, $cmd) = $row;
    $arr = &$tree_map;
        while($depth--) {
         end($arr ); 
         $arr = &$arr [key($arr )];
    }
    $arr [$cmd] = null;             
}

但我不确定这是最好的方式。。。

我认为这应该能奏效(至少在我的测试中,它对您的数据有效)。请注意,此代码不进行太多错误检查,并希望输入数据的顺序正确(即从0级开始,没有孔)。

<?php
$input = explode("'n",file_get_contents($argv[1]));
array_shift($input);
$data = array();
foreach($input as $dir)
{
    if(count($parts = str_getcsv($dir, ';')) < 2)
    {
        continue;
    }
    if($parts[0] == 0)
    {
        $last = array('_id' => null,
                      'name' => $parts[1],
                      'path' => $parts[1]);
        $levels = array($last);
        $data[] = $last;
    }
    else
    {
        $last = array('id' => null,
                      'name' => $parts[1],
                      'path' => $levels[$parts[0] - 1]['path'] . ',' . $parts[1]);
        $levels[$parts[0]] = $last;
        $data[] = $last;
    }
}
print_r($data);
?>

"最好"的方法是不要以CSV格式存储数据,因为这是错误的工作工具。

也就是说,给你:

<?php
$lines = file('/path/to/your/csv_file.csv');
$directories = array();
$path = array();
$lastDepth = NULL;
foreach ($lines as $line) {
    list($depth, $dir) = str_getcsv($line, ';');
    // Skip headers and such
    if (!ctype_digit($depth)) {
        continue;
    }
    if ($depth == $lastDepth) {
        // If this depth is the same as the last, pop the last directory
        // we added off the stack
        array_pop($path);
    } else if ($depth == 0) {
        // At depth 0, reset the path
        $path = array();
    }
    // Push the current directory onto the path stack
    $path[] = $dir;
    $directories[] = array(
        '_id' => NULL,
        'name' => $dir,
        'path' => implode(',', $path)
    );
    $lastDepth = $depth;
}
var_dump($directories);

编辑:

值得一提的是,一旦您在PHP中拥有了所需的嵌套结构,那么使用json_encode()、serialize()或其他格式将其再次存储到磁盘上并去掉CSV文件可能是一个好主意。然后,只要您再次需要,就可以使用json_decode()或unserialize()将其恢复为PHP数组格式。