如何在Python中查找文件并循环它们?
我有一个Bash脚本,其中包含以下代码:如何在Python中查找文件并循环它们?,python,file,search,find,Python,File,Search,Find,我有一个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
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做类似的事情?我可以想象生成一个包含各种已找到文件及其完整路径或相对路径的列表,然后在该列表上循环,但我不确定如何生成这样的列表。查看os.walk
它非常适合梳理文件系统
这里有一些代码可以帮助您继续
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)
我从常用的
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
我会这样做:
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()
这样做很容易
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')]
非常感谢你在这方面的帮助。您的代码提供了一个很好的指南。正则表达式的考虑特别有用。谢谢你的建议。我看到@stevieb是以这种方式实现的。非常感谢您在这方面的指导。您的解决方案几乎是直接翻译我的Bash代码,这有助于理解您的方法。非常感谢您的建议。我不熟悉glob,但它使用起来非常清晰有效,所以谢谢你的建议。啊,这很方便。非常感谢分享你的代码!你对每个答案的反馈是一个优秀的提问者的关键。在这样的地方很少见。