【问题标题】:Extracting a diffrentiating numerical value from multiple files - PowerShell/Python从多个文件中提取不同的数值 - PowerShell/Python
【发布时间】:2022-10-23 02:24:44
【问题描述】:

我有多个包含不同文本的文本文件。 它们都包含我感兴趣的相同 2 行的单一外观:

================================================================
Result: XX/100

我正在尝试编写一个脚本来收集所有这些 XX 值(0 到 100 之间的数值),并将它们粘贴到一个 CSV 文件中,其中 A 列中的文本文件名和 B 列中的数值。

为此,我考虑过使用 Python 或 PowerShell。

如何识别“===..”字符串下出现“Result”的行,收集其内容直到'\n',然后将其从“Result:”和“/100”中剥离?

“结果”和其他数值可能出现在文件中,但绝不会以引用的格式出现,并且在“=====”下方,就像我感兴趣的行一样。

谢谢!

编辑:我写了这个可怜的天真尝试来收集数值。

import os
dir_path = os.path.dirname(os.path.realpath(__file__))
for filename in os.listdir(dir_path):
    if filename.endswith(".txt"):
        with open(filename,"r") as f:
            lineFound=False
            for index, line in enumerate(f):
                if lineFound:
                    line=line.replace("Result: ", "")
                    line=line.replace("/100","")
                    line.strip()
                    grade=line
                    lineFound=False
                    print(grade, end='')
                    continue
                if index>3:
                    if "================================================================" in line:
                        lineFound=True

我仍然很乐意了解是否有使用 PowerShell tbh 的简单方法 对于输出,我使用 csv writer 将结果一一附加到文件中。

【问题讨论】:

  • 维护一个 2 级双端队列。使用正则表达式来识别 Result: XX/100 模式。回顾一下(在双端队列中),看看前一行是否以 64 次重复的 '=' 开头。提取 XX 值(有很多方法可以做到这一点)。使用适合管理 CSV 文件的库 - 例如,CSV,熊猫

标签: python powershell csv


【解决方案1】:

所以这里涉及两个步骤,首先是获取文件列表。在 stackoverflow 上有大量的答案,但 this one 是愚蠢的完整的。

一旦你有了文件列表,你可以简单地一个一个地加载文件,然后做一些简单的string.split() 来获得你想要的值。

最后,将结果写入 CSV 文件。由于 CSV 文件很简单,因此您不需要为此使用 CSV 库。

请参阅下面的代码示例。请注意,我复制/粘贴了用于从我的个人 github 存储库生成文件列表的函数。我经常重复使用那个。

import os


def get_files_from_path(path: str = ".", ext:str or list=None) -> list:
    """Find files in path and return them as a list.
    Gets all files in folders and subfolders
    See the answer on the link below for a ridiculously
    complete answer for this.
    https://stackoverflow.com/a/41447012/9267296
    Args:
        path (str, optional): Which path to start on.
                              Defaults to '.'.
        ext (str/list, optional): Optional file extention.
                                  Defaults to None.
    Returns:
        list: list of file paths
    """
    result = []
    for subdir, dirs, files in os.walk(path):
        for fname in files:
            filepath = f"{subdir}{os.sep}{fname}"
            if ext == None:
                result.append(filepath)
            elif type(ext) == str and fname.lower().endswith(ext.lower()):
                result.append(filepath)
            elif type(ext) == list:
                for item in ext:
                    if fname.lower().endswith(item.lower()):
                        result.append(filepath)
    return result


filelist = get_files_from_path("path/to/files/", ext=".txt")
split1 = "================================================================
Result: "
split2 = "/100"


with open("output.csv", "w") as outfile:
    outfile.write('filename, value
')
    for filename in filelist:
        with open(filename) as infile:
            value = infile.read().split(split1)[1].split(split2)[0]
        print(value)
        outfile.write(f'"{filename}", {value}
')

【讨论】:

    【解决方案2】:

    你可以试试这个。

    在此示例中,写入 CSV 的文件名将是其完整(绝对)路径。您可能只需要基本文件名。

    使用相同的(尽管看似不必要)机制来派生源目录。将 Python 脚本与数据放在同一目录中是不寻常的。

    import os
    import glob
    
    equals = '=' * 64
    dir_path = os.path.dirname(os.path.realpath(__file__))
    outfile = os.path.join(dir_path, 'foo.csv')
    with open(outfile, 'w') as csv:
        print('A,B', file=csv)
        for file in glob.glob(os.path.join(dir_path, '*.txt')):
            prev = None
            with open(file) as indata:
                for line in indata:
                    t = line.split()
                    if len(t) == 2 and t[0] == 'Result:' and prev.startswith(equals):
                        v = t[1].split('/')
                        if len(v) == 2 and v[1] == '100':
                            print(f'{file},{v[0]}', file=csv)
                            break
                    prev = line
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-07
      • 1970-01-01
      • 2020-11-26
      • 2017-05-12
      • 2017-02-12
      • 1970-01-01
      相关资源
      最近更新 更多