获取文件夹和文件的 JSON 树(但仅限于包含给定字符串的文件)

Posted

技术标签:

【中文标题】获取文件夹和文件的 JSON 树(但仅限于包含给定字符串的文件)【英文标题】:Getting JSON tree of folders and files (but only with files containing given string) 【发布时间】:2014-12-26 19:45:43 【问题描述】:

我需要得到一种 JSON 格式的过滤目录/文件结构。

具体来说,我只需要包含包含给定字符串的文件,并且只包含包含此类文件的目录(在它们自身中,或在它们的某些后代中)。

这段代码:

import os
import json

def path_to_dict(path):
    d = 'name': os.path.basename(path)
    if os.path.isdir(path):
        d['type'] = "directory"
        d['children'] = [path_to_dict(os.path.join(path,x)) for x in os.listdir\
(path)]
    else:
        d['type'] = "file"
    return d

print json.dumps(path_to_dict('.'), indent=2)

以我想要的格式为我提供所有目录和文件的漂亮 JSON 树,从当前目录开始:


    "type": "directory",
    "name": ".",
    "children": [
    
      "type": "file", 
      "name": "attribute_container.c"
    , 
    
      "type": "file", 
      "name": "node.c"
    , 
    
      "type": "directory", 
      "name": "power", 
      "children": [
        
          "type": "file", 
          "name": "clock_ops.c"
        , 
        
          "type": "file", 
          "name": "common.c"
        , 
        
          "type": "file", 
          "name": "domain.c"
        , 
        
          "type": "file", 
          "name": "domain_governor.c"
        , 
        
          "type": "file", 
          "name": "generic_ops.c"
        , 
        
          "type": "file", 
          "name": "wakeup.c"
        
      ]
    , 
    
      "type": "directory", 
      "name": "regmap", 
      "children": [
        
          "type": "file", 
          "name": "internal.h"
        , 
        
          "type": "file", 
          "name": "Kconfig"
        , 
        
          "type": "file", 
          "name": "Makefile"
        , 
        
          "type": "file", 
          "name": "regcache-flat.c"
        , 
        
          "type": "file", 
          "name": "regmap-spmi.c"
        , 
        
          "type": "file", 
          "name": "regmap.c"
        
      ]
    , 
    
      "type": "file", 
      "name": "soc.c"
    , 
    
      "type": "file", 
      "name": "syscore.c"
    , 
    
      "type": "file", 
      "name": "topology.c"
    , 
    
      "type": "file", 
      "name": "transport_class.c"
       ] 

但是,我只需要包含给定字符串的文件。此外,只有包含此类文件的文件夹或其某些后代包含此类文件。 (可以这么说,我需要一种“修剪”)

我知道在文件中查找字符串的解决方案:

my_file = ...
my_string = ...
infile = open(my_file,"r")

numlines = 0
found = 0
for line in infile:
    numlines += 1
    found += line.count(my_string)
infile.close()

print "%s was found %i times in %i lines", %string, %found, %numlines

但我很难将它集成到问题顶部的代码中。

感谢任何提示或建议。

【问题讨论】:

使用 os.walk(path) 而不是递归调用 path_to_dict。 pythoncentral.io/… 在 else 之后,在 open(path).read() 中包含 if my_string: then d['type'] = 'file'。这只会为包含该字符串的文件创建条目。 【参考方案1】:

我不想用os.walk()重写你的代码。我只会对你的代码做一些小改动。

关键是使用 None 作为标记值来修剪文件和清空children 列表来修剪目录。该实现写得不好,但它向您展示了如何使用测试的核心。

import os
import json

def check_in_file(my_file,my_string):
    with open(my_file) as f:
        try:
            return my_string in f.read()
        except:
            return False

def path_to_dict(path, my_string=None):
    d = 'name': os.path.basename(path)
    if os.path.isdir(path):
        d['type'] = "directory"
        d['children'] = []
        paths = [os.path.join(path,x) for x in os.listdir(path)]
        #Just the children that contains at least a valid file
        for p in paths:
            c = path_to_dict(p, my_string)
            if c is not None:
                d['children'].append(c)
        if not d['children']:
            return None
    else:
        if my_string is not None and not check_in_file(path,my_string):
            return None
        d['type'] = "file"
    return d

print(json.dumps(path_to_dict('.',), indent=2))
print(json.dumps(path_to_dict('.','kkkkk'), indent=2))

【讨论】:

对我来说,代码很漂亮。我刚刚测试了它,十几个案例。它就像魅力一样。我花了好几个小时试图设计解决方案,但现在你救了我。谢谢!该代码将用于C源代码的重要探索性可视化!

以上是关于获取文件夹和文件的 JSON 树(但仅限于包含给定字符串的文件)的主要内容,如果未能解决你的问题,请参考以下文章

为什么Python`pip.main(['install',...])`给出了ImportError,但仅限于包含dot的包名?

Mysql列表日期范围之间的日期,但仅限于一周中的特定日期

将逗号转换为点和数字,但仅限于一定数量的变量

Android 应用程序崩溃,但仅限于三星 Galaxy

删除括号之间的文本,但仅在给定条件下

Rangy 库的 Vue 错误:“...”不是函数(但仅限于钩子内部)