我有以下目录/文件设置(这是简化的):
Ce
+---top.txt
+---X0.0
| |
| +---Y0.0
| | |
| | +---X0.0Y0.0Z0.0.dat
| | +---X0.0Y0.0Z0.05.dat
| +---Y0.05
| |
| +---X0.0Y0.05Z0.0.dat
| +---X0.0Y0.05Z0.05.dat
+---X0.05
|
+---Y0.0
| |
| +---X0.0Y0.0Z0.0.dat
| +---X0.0Y0.0Z0.05.dat
+---Y0.05
|
+---X0.0Y0.05Z0.0.dat
+---X0.0Y0.05Z0.05.dat
在每个 Y 目录中,我需要创建一个“psub”文件,其中包含将 .dat 文件列表附加到文件“top.txt”的副本。
我尝试使用 python 3 中的 os.walk 函数来执行此操作:但是我遇到了两个问题:
1、X0.0目录下出现新的psub文件
2. 代码没有列出任何文件名(大概是因为它没有找到任何文件名),然后给出错误,指出无法找到 X0.05 目录。
到目前为止,我有以下代码:
import os
with open('top.txt', 'r') as reader:
data=reader.read()
for root, dirs, files in os.walk('.'):
for folder in dirs:
os.chdir(os.path.join(root, folder))
with open('psub', 'a') as writer:
writer.write(data)
for names in files:
if names.endswith('.dat'):
print('gulp <' + names + '> ', end='', file=writer)
print(names.rsplit('.',1)[0], end='', file=writer)
print('.out', file=writer)
生成的 psub 文件应为:
#!/bin/bash
#MOAB -l walltime=48:00:0
#MOAB -j oe
#MOAB -N GULP-job
cd "$PBS_O_WORKDIR"
module load apps/gulp
#!/bin/bash
gulp <X0.00Y0.00Z0.00.dat> X0.00Y0.00Z0.00.out
gulp <X0.00Y0.00Z0.05.dat> X0.00Y0.00Z0.05.out
其中前七行位于top.txt中。
任何关于我哪里出错的(简单的)指示将不胜感激。 干杯
最佳答案
walk
旨在自行递归地迭代所有目录,因此
无需自己遍历所有子目录。摆脱 for folder in dirs:
循环。
我还建议用单个字符串格式命令替换多个打印语句,如下所示:
print('gulp <{}.dat> {}.out'.format(names.rsplit('.',1)[0]), file=writer)
#or use writer.write(), to make it more transparent
您还应该重命名一些变量,以便它们更好地代表它们的用途;例如,在最后一个循环中调用迭代变量 names
会产生误导,因为它实际上不是名称的集合,而是单个文件名。
编辑:为了避免创建额外的空文件,您需要检查目录是否需要创建文件。您可以通过迭代文件名并设置一个标志(如果有需要处理的.dat
文件)来完成此操作。
编辑2:分解代码,并重命名一堆东西,所以现在更清晰了。
这些修改的总和导致:
import os
def isDat(filename): return filename.endswith('.dat')
def hasDat(filenames): #this method checks if it contains one ending with '.dat'
for filename in filenames:
if isDat(filename): return true
return false
def datFiles(filenames):
for filename in filenames:
if isDat(filename): yield filename
def gulpLines(filenames):
for filename in datFiles(filenames):
yield 'gulp <{}.dat> {}.out\n'.format(filename.rsplit('.',1)[0])
def makePsub(root, filenames, prologue):
with os.open(os.path.join(root, 'psub'), 'a') as writer:
#try putting 'psub.sh' instead, perhaps it is getting confused with no extension
writer.write(prologue)
for gulpLine in gulpLines(filenames):
writer.write(gulpLine)
with open('top.txt') as reader:
prologue=reader.read() #this is a much more descriptive name
#you can close it as soon as you have its contents
for root, dirs, filenames in os.walk('.'):
if hasDat(filenames):
makePsub(root, filenames, prologue)
Python 应该由许多小函数组成,而不是嵌套二十层的又大又长的怪物。
此外,通过分解代码,您可以准确确定代码的哪一部分导致了问题,因为您可以单独测试每个函数。如果您怀疑(例如)问题是无法正确识别 .dat
文件,您可以单独测试 isDat
函数,直到修复它。如果您怀疑问题出在写入 psub
文件上,您可以通过将 gulpLines
替换为虚拟实现(其中使用预定的结果列表,或者让用户手动执行,而不是实际生成它们)。
您可以做的另一件事是在循环内插入调试代码。例如,在您(应该)向 writer
写入 data
后插入一条输出 writer
内容的语句,以检查您是否确实拥有您期望的内容。另一个调试选项是运行部分代码;例如,运行一个仅执行 walk 循环的程序,或仅将数据
写入文件,或仅解析文件名(打印它将写入文件的内容)控制台,用于检查目的)。
关于python3 : having problems with os. 步行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18829936/