質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

5回答

7175閲覧

pythonでのファイル検索、読み込みについて

u_k_statistics

総合スコア44

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2016/06/06 08:23

例えば
A/B/C/D/
の中にEというディレクトリとFというディレクトリがあったとします。
EとFにはそれぞれe001.txt〜e100.txtとf001.txtf100.txtが入ってるとします。
このような状況下で、e050.txt
e059.txtとf050.txt~f059.txtのファイルを一度に読み込みたいのですがどのようにしたらいいのでしょうか?

検索対象のディレクトリが1つであれば(仮にEとします)
import glob
files = []
filesnames = []
files = glob.glob('A/B/C/D/E/e05*.txt')
for i in range(len(files)):
filesnames.append(os.path.basename(files[i]))
for i in range(len(files)):
openfile = codecs.open(''A/B/C/D/E/' + filesnames[i],"r",'utf-8')
のようにしているのですが、複数のディレクトリを一度に検索して取得する方法がわかりません。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

どういうパターンがあるかわからないので、globでまとめて処理しないで os.listdir で地道に処理するか、 os.walk でディレクトリを走査しながら処理してはどうでしょうか?

python

1>>> import os 2>>> base = 'A/B/C/D/' 3>>> for dirname in os.listdir(base): 4... path = os.path.join(base, dirname) 5... if os.path.isdir(path): # ディレクトリだったらファイルの一覧を取得 6... for filename in os.listdir(path): 7... if filename.endswith('.txt'): 8... filepath = os.path.join(path, filename) 9... # ここにファイルに対する処理を書く 10...

投稿2016/06/08 03:30

編集2016/06/08 06:16
takanory

総合スコア125

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

二回とってくっつけちゃえばいい

python

1files = glob.glob('A/B/C/D/E/e05?.txt') 2files.extend(glob.glob('A/B/C/D/F/f05?.txt'))

投稿2016/06/06 08:51

matobaa

総合スコア2493

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u_k_statistics

2016/06/06 09:08

matobaaさん 回答ありがとうございます。 上のようにfilesに付け加える?形でfilesに2にのパスが入ることになると思うのですが、ファイルを検索する際には for i in files: のようにして検索しなければならないのでしょうか?
matobaa

2016/06/06 09:14

その通りです。files はリストなので、要素を一つずつ取り出すには for-in を使えばいいです。簡単な変換処理だったら map() を使ってもいいでしょう。
guest

0

glob と filter をつかってかいてみました。
a.py

import glob import os def match(n): s = os.path.split(n) file_name = s[1] dir_name = os.path.split(s[0])[1] return file_name.startswith(dir_name.lower() + '05') print(filter(lambda n: match(n), glob.glob('./data/*/*05[0-9].txt')))

実行例

$ tree data data ├── A │   ├── a050.txt │   ├── a100.txt │   └── b050.txt ├── B │   ├── a050.txt │   ├── b050.txt │   └── b100.txt └── XYZ ├── a050.txt ├── xyz050.txt └── xyz100.txt $ python a.py ['./data/A/a050.txt', './data/B/b050.txt', './data/XYZ/xyz050.txt']

投稿2016/06/06 14:02

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

以下でどうでしょうか。
files = glob.glob('A/B/C/D/[EF]/[fe]05*.txt')

ただし、Eの配下に f05.. というファイルがあった場合、マッチしてしまいますが。
コメントにあるようにディレクトリ名が1文字でないとすると難しいです。

投稿2016/06/06 08:51

yoshi777

総合スコア674

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u_k_statistics

2016/06/06 09:08

yoshi777さん 回答ありがとうございます。 やはり1文字の時に有効な手段のようですね。
guest

0

ベストアンサー

[ ]で囲むと、いずれかの文字というパターンになります。
なので、A/B/C/D/[EF]/e05*.txtとすれば、EFの両方を検索できます。

ただ、おそらく実際のディレクトリーは1文字ではないのですよね?

投稿2016/06/06 08:42

編集2016/06/06 08:43
argius

総合スコア9388

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u_k_statistics

2016/06/06 08:45

argiusさん 回答ありがとうございます。 そんな方法があるんですね。だた予測されている通りで実際のディレクトリーは1文字ではありません。 その場合は長くなりすぎるためあまり有効な手段ではないということでしょうか?
argius

2016/06/06 09:01

あとはいったん全部取得してから正規表現で絞り込みとかですかね。 これだと難易度が少しあがります。 matobaaさんの回答にある方法の方が簡単ですけど、そうでないとちょっと難しくなりそうです。
argius

2016/06/06 09:19

filterを使って、あとから絞り込むならこんな感じで。 files = list(filter(lambda x: 'EEE/e' in x or 'FFF/f' in x, glob.glob('*/?05?.txt'))) あとはファイル名のパターン次第ですかね。
u_k_statistics

2016/06/07 01:38

argiusさん ファイル名のパターンとしてはj*.txtを全部拾いたいです。 ディレクトリは 〇〇/××/aaaa−001 から 〇〇/××/aaaa−015 までの15ほどの中から検索したいです。 この場合ですとなにかいい方法はありますか? よろしくお願いします。
argius

2016/06/07 03:29

matobaaさんの回答のように結合を使って files = glob.glob('〇〇/××/aaaa−00[0-9]*/j*.txt') + glob.glob('〇〇/××/aaaa−1[0-5]/j*.txt') こうするか、 これでさらに条件を絞りたいなら、やはりfilter関数で細かく条件を指定していくのが 良いんじゃないでしょうか。 if文は複数書いても良いです。 def f(filepath): if '...' in filepath: return true return false files = list(filter(f, glob.glob('〇〇/××/aaaa−0*/j*.txt')))
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問