我有以下目录/文件设置(这是简化的):
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.新的psub文件出现在X0.0目录中
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中。
关于我出错的地方的任何(简单)指针将非常感激。 干杯
答案 0 :(得分:3)
walk
旨在以递归方式遍历所有目录,因此
没有必要自己遍历所有子目录。摆脱for folder in dirs:
循环。
我还建议用单个字符串格式命令替换多个print语句,如下所示:
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
的内容,以检查您是否确实拥有了您希望拥有的内容。另一个调试选项是运行部分代码;例如,运行一个只执行walk循环的程序,或者只将data
写入文件,或者只解析文件名(将将写入文件的内容打印到控制台,用于检查目的)。