使用split()和glob.glob()没有输出匹配的文件名

时间:2018-02-15 21:53:39

标签: python python-3.x split glob

我试图在一堆具有以下形式的子目录中找到所有文件:
sub-num_ses-wavenum_task-name_run-num_info.ext
 或
sub-num_ses-wavenum_task-name_info.ext

文件名run-num的部分可以采用run-01run-15或更高的格式,具体取决于匹配task-name段的数字文件。如果没有重复的任务名称,则没有run-num

脚本可以成功输入目录,我可以通过在_分隔

将文件名分成块
niidir="some/path"  
for dirpath, dirnames, files in os.walk(niidir): 
    for dirname in dirnames:
        if dirname == "fmap" or dirname == "anat" or dirname == "func":
            fullpath = dirpath + "/" + dirname
            for files in fullpath:
                for file in os.listdir(fullpath):
                    chunks = file.split("_")
                        print(chunks)

print(chunks)将给出输出:
['sub-num', 'ses-wavenum', 'task-name', 'run-num', 'info.ext']
或者,如果没有run-num
['sub-num', 'ses-wavenum', 'task-name', 'info.ext']

我也可以打破我要检查的部分,看看它是否是一个运行编号:

niidir="some/path"  
for dirpath, dirnames, files in os.walk(niidir): 
    for dirname in dirnames:
        if dirname == "fmap" or dirname == "anat" or dirname == "func":
            fullpath = dirpath + "/" + dirname
            for files in fullpath:
                for file in os.listdir(fullpath):
                    chunks = file.split("_")
                        print(chunks[-2])

退货,例如:
run-02,如果有运行编号,或者是 task-name,如果没有运行编号。

但是,我的问题是我似乎无法列出那些有运行编号的文件:

niidir="some/path"  
for dirpath, dirnames, files in os.walk(niidir): 
    for dirname in dirnames:
        if dirname == "fmap" or dirname == "anat" or dirname == "func":
            fullpath = dirpath + "/" + dirname
            for files in fullpath:
                for file in os.listdir(fullpath):
                    chunks = file.split("_")
                    if chunks[-2]) == glob.glob("run-[0-9]{2}"):
                        print(chunks[-2])

根本没有输出。

我不知道为什么我找不到匹配的刺痛。

编辑1:
文件路径为niidir/sub-num/ses-num/sequence/files

clean_nii中有多个子num目录,每个子num目录中有多个ses-num目录。每个ses-num目录包含以下部分或全部序列目录:“anat”,“func”或“fmap”,其中包含文件。

编辑2:我不是程序员。请不要假设我知道你在说什么,即使它是“基本的”。我正在努力。

1 个答案:

答案 0 :(得分:0)

您对glob使用了错误的语法,并且您正在错误地使用通配符。您的glob()调用想要在单个数字后匹配文字{2}字符串,并且您尝试使用生成文件列表的函数来测试字符串是否与模式匹配。

匹配文件的正确模式是:

glob.glob("run-[0-9][0-9]*")

Glob模式不是正则表达式。有关详细信息,请参阅wikipedia article on glob syntaxfnmatch module

接下来,glob.glob()查找文件系统上的文件,并返回匹配文件名的列表。上述模式没有路径信息,因此只列出本地工作目录中的文件。您必须使用glob.glob(os.path.join(fullpath, "run-[0-9][0-9]*")来匹配目录中的特定文件,此时列表将包含完整路径。您不应该将该列表与单个字符串进行比较,chunks[-2] 从不将等于匹配文件名列表。

如果你想看看你的字符串是否与特定的通配模式匹配,你可以使用fname.fnmatch() function

if fnmatch.fnmatch(chunks[-2], 'run-[0-9][0-9]'):

现在,您实际上正在测试文件名部分是否包含开头的字符串run-,后跟两位数。

接下来,您的for files in fullpath循环遍历fullpath字符串的个别字符。你重复这个循环len(filepath)次,而不需要重复任何事情。你忽略了files变量,你只是做了不必要的额外工作。

接下来,您的代码仍在执行超出其需要的工作。 os.walk() 列出目录中的文件名,但您的代码会通过os.listdir()调用冗余地列出它们。在找到这些特定子目录后修剪dirnames列表,或者为匹配的子目录测试dirpath并改为处理files

import os
import os.path
import fnmatch

niidir="some/path" 

for dirpath, dirnames, files in os.walk(niidir): 
    directory_name = os.path.basename(dirpath)
    if directory not in {'fmap', 'anat', 'func'}:
        # Only process files in specific subdirectories
        continue
    for filename in fnmatch.filter(files, "run-[0-9][0-9]*"):
        # process matching file

我使用fnmatch.filter() function过滤掉files生成的os.walk()列表中的匹配名称。

或者,如果您要处理目录中的所有文件并仅测试较大列表中的特定文件,请坚持fnmatch.fnmatch()

for dirpath, dirnames, files in os.walk(niidir): 
    directory_name = os.path.basename(dirpath)
    if directory not in {'fmap', 'anat', 'func'}:
        # Only process files in specific subdirectories
        continue
    for filename in files:
        prefix, remainder = filename.partition('_')
        if fnmatch.fnmatch(prefix, 'run-[0-9][0-9]'):
            # filename starts with a run-number.
        else:
            # do something else