【问题标题】:How can I find files and then loop over them in Python?如何找到文件然后在 Python 中遍历它们?
【发布时间】:2015-07-07 20:04:22
【问题描述】:

我有一个包含以下代码的 Bash 脚本:

merge_ROOT_files(){
    output_file=""$(date -u "+%Y-%m-%dT%H%M%S")"Z_merged.root"
    list_of_files="$(find . -name \*.root -type f)"
    command="hadd "${output_file}""
    for current_file in ${list_of_files}; do
        echo "found ROOT file "${current_file}""
        command=""${command}" "${current_file}""
    done
    echo "merge ROOT files to output ROOT file "${output_file}""
    echo "merge command: ${command}"
    eval "${command}"
}

merge_ROOT_files

您可以看到它递归搜索以.root 结尾的文件,然后循环遍历这些文件。我怎么能在 Python 中做类似的事情?我可以想象生成一个包含完整或相对路径的各种找到文件的列表,然后循环遍历该列表,但我不确定如何生成这样的列表。

【问题讨论】:

  • 您为每个答案发布的反馈是出色的提问者的原因。在 SO 中很少见。

标签: python file search find


【解决方案1】:

glob 使得做这种事情变得非常容易。

import os
import glob

# Get full path for .root files
root_files = glob.glob('/your_path/*.root')

# Only get root file names
root_file_names = [os.path.basename(f) for f in glob.iglob('/your_path/*.root')]

【讨论】:

  • 非常感谢您的建议。我对glob不熟悉,但是使用起来非常清晰高效,所以感谢您的建议。
【解决方案2】:

这里有一些代码应该可以帮助你。

import os
import re

searchdir = '.'
ext_rx = '\.root$'

filelist = []

for root, dir, files in os.walk(searchdir):
    for file in files:
        if re.search(ext_rx, file):
            filelist.append(os.path.join(root, file))

for file in filelist:
    print(file)

【讨论】:

  • 非常感谢您的帮助。您的代码提供了一个很好的指导。正则表达式的考虑特别有帮助。
【解决方案3】:

查看 os.walk

非常适合梳理文件系统

http://www.tutorialspoint.com/python/os_walk.htm

【讨论】:

  • 感谢您的建议。我看到@stevieb 以这种方式实现了a solution
【解决方案4】:

我会这样做:

import os
import fnmatch
import subprocess
import datetime


def merge_ROOT_files():
    output_file = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H%M%SZ_merged.root")

    root_files = [
        os.path.join(root, filename)
        for root, dirs, files in os.walk('.')
        for filename in files
        if fnmatch.fnmatch(filename, '*.root')
    ]

    # Remove 'echo' when you want to go live.
    subprocess.check_call(['echo', 'hadd', output_file]+root_files)

if __name__ == "__main__":
    merge_ROOT_files()

【讨论】:

  • 非常感谢您对此的指导。您的解决方案几乎是我的 Bash 代码的直接翻译,这有助于理解您的方法。
【解决方案5】:

我从我常用的utils中提取了这段代码

import os
import os.path

def flatten( seq ) :
  res = []
  for item in seq :
    if ( isinstance( item, ( tuple, list ) ) ) :
      res.extend( flatten( item ) )
    else:
      res.append( item )
  return res


def get_roots( path ) :
    """Get a list of .root files in a given directory.
    """
    rootfiles2 = []
    os.listdir( path )
    for root, dirs, files in os.walk( path, topdown=True ) :
        #print ( 'root =', root, ', dirs =', dirs, ', files =', files )
        print ( 'root =', root )
        print ( 'dirs =', dirs )
        print ( 'files =', files )
        # Get only .root files
        rootfiles2.append( [ root + '/' + file for file in files if ( file.split('.')[-1] == 'root' ) ] )
    rootfiles = list( flatten( rootfiles2 ) )
    return rootfiles

【讨论】:

  • 啊,这个很方便。非常感谢您分享您的代码!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
  • 2016-02-26
相关资源
最近更新 更多