递归导航文件系统以成对分析文件

2024-09-28 22:19:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python脚本(我们称之为myscript.py),我想应用于嵌套目录结构中的一堆文件。我将在集群环境中并行运行该脚本的调用,因此我想为此编写一个简短的bash脚本。在

因此给定一对文件,如xyz_1.gzxyz_2.gz,它们嵌套在如下文件夹中:

A > ... > C1 > xyz_1.gz
A > ... > C1 > xyz_2.gz
A > ... > C1 > bunch of other files
A > ... > C2 > xyy_1.gz
A > ... > C2 > xyy_2.gz
A > ... > C2 > bunch of other files
A > ... > C3 > zzz_1.gz
A > ... > C3 > zzz_2.gz
A > ... > C3 > bunch of other files
A > B > some other things

这是一个愚蠢的例子,但我希望它至少传达了结构。在

我希望能够迭代目录结构并调用我的脚本:

^{pr2}$

这样,输出文件就会在相应的文件夹中结束。在

到目前为止,我看到的大多数递归解决方案都对每个单独的文件使用find或{},但是我也需要位置,以便将它们成对地放入磁盘并在适当的位置写入磁盘。在

有什么建议吗?在

编辑:从我目前得到的答案来看,我想澄清一下,我事先并不知道以下三个参数:

  1. 保存.gz文件的子目录的深度,也就是说,我不知道中间目录之间有多少个
  2. 子目录的名称
  3. 文件的名称,除了后缀为“1/\u 2”之外,它们是相同的

Tags: 文件of目录脚本文件夹files结构other
2条回答

(回答编辑后的问题。)

在shell中实现这一点比较困难(可读性较差),因此我求助于Python:

#!/usr/bin/env python3
import os
import re
import pprint
from sets import Set
from subprocess import call

group1 = {} # collect here the filenames for _1
group2 = {} # collect here the filenames for _2

for root, directories, filenames in os.walk('.'):
        for filename in filenames:
                ff = os.path.join(root,filename)
                if filename.endswith("_1.txt"):
                        base = re.sub('_1\.txt$','', ff)
                        group1[base] = ff
                if filename.endswith("_2.txt"):
                        base = re.sub('_2\.txt$','', ff)
                        group2[base] = ff

#pprint.pprint(group1)
#pprint.pprint(group2)

# find common ones: the dirs which contain the files with the common prefix:
list1 = Set(group1.keys()).intersection(Set(group2.keys()))

#pprint.pprint(list1)

# call the myscript.py
cwd = os.getcwd()
for base in list1:
        path, filename = os.path.split(base)
        #print path," ",filename
        try:
                os.chdir(path)
                call(['echo', 'myscript.py', filename+"_1.txt", filename+"_2.txt", "outputfile"])
        finally:
                os.chdir(cwd)

(为糟糕的Python风格感到抱歉:我实际上是一个Perl程序员。)


Most recursive solutions I have seen so far use either find or grep for each individual file however I need the location as well, to get them in pairs and write to disk at the appropriate place.

不要迭代文件-遍历目录。shell中的示例:

^{pr2}$

或者,您仍然可以迭代文件,让find为我们检查其中一个文件。然后从找到的文件名中提取目录:

find -type f -name xyz_1.gz -print |
while read FN; do
    DIR=`dirname $FN`
    test -r $DIR/xyz_2.gz -a -r $DIR/some_other_file || continue
    ( cd $DIR; myscript.py xyz_1.gz xyz_2.gz outputfile )
done

此外,您还可以将开头的cd $DIRos.chdir());将目录作为参数或env var传递到Python脚本本身,并检查输入文件(例如,如果文件不存在,则自动退出)。在

下面是执行以下操作的bash脚本:

for i in */*/*.gz
do
    echo "$i"
done | sort | while read -r line || [[ -n "$line" ]]
do
    read -r nextline
    $(cd $(dirname "$line") && python3 ~/A/myscript.py "$line" "$nextline" ./outputfile) && echo "Success"
done

脚本在递归性方面非常严格,但我根据您的目录结构应用了它

不知道具体有多少文件,但类似的东西可以为您工作:

^{pr2}$

我已经创建了一个虚拟的python脚本,它写出作为参数提供给它的文件名。这是python脚本:

import sys
#0 is script name itself
input_file1=sys.argv[1]
input_file2=sys.argv[2]
output_file=sys.argv[3]
s=input_file1+"\n"+input_file2+"\n"
with open(output_file, "w") as f:
    f.write(s)

相关问题 更多 >