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

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

ただいまの
回答率

90.00%

再帰的に処理する時、指定したディレクトリを除外したい

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,149

shamimatsu

score 20

python2.7です。
色々考えましたがどうしても除外する方法がわからなかったため質問させていただきます。

例ではテキストデータをまとめてエディタに送るという処理なのですが、
oldという名前のフォルダに入っているデータだけ処理から除外しA.txt、B.txtだけ開きたいです。
良い方法がございましたら教えていただきたいです。

構造
textdir
└ A.txt
  B.txt
  old
   └ C.txt

 現状のコード

# coding=utf-8
import os
import subprocess


memo = 'C:/Program Files/Notepad++/notepad++.exe'
dir_path = 'C:/Users/ユーザー名/Desktop/textdir'


for root, dirs, files in os.walk(dir_path):
    for file_name in files:
        paths = os.path.join(root, file_name)
    for dir_name in dirs:
        dir = os.path.join(root, dir_name)

        if os.path.basename(dir) == 'old':
            pass
        elif os.path.isfile(paths):
           subprocess.Popen([memo, dir_path])
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

 os.walk() で走査するディレクトリを変更する。

os.walk() で topdown=True とした場合、返り値の dirnames を in-place で変更することで、走査するディレクトリを変更できます。

topdown が True のとき、呼び出し側は dirnames リストを、インプレースで変更でき、 
walk()dirnames に残っているサブディレクトリ内のみを再帰します。
これにより、検索を省略したり、特定の訪問順序を強制したり、呼び出し側が walk() を再開する前に、
呼び出し側が作った、または名前を変更したディレクトリを、 walk() に知らせたりすることができます。 

 サンプルコード

# coding: utf-8
import os
import subprocess

exe_path = r'C:/Program Files/Notepad++/notepad++.exe'
target_path = '/root'

for root, dirnames, filenames in os.walk(target_path, topdown=True):
    # old を走査するディレクトリから除く。
    dirs[:] = [d for d in dirnames if d != 'old']

    for filename in filenames:
        file_path = os.path.join(root, filename)  # ファイルパス
        ext = os.path.splitext(file_path)[1]  # 拡張子
        if ext == '.txt':
            # テキストファイルを開く。
            print('Open', file_path)
            subprocess.Popen([exe_path, file_path])

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/27 19:30

    回答ありがとうございます!A.txt、B.txtだけ開くことができました。
    dirs[:]部分が僕にはまだ難しかったため少しずつ見ながら理解していきたいと思います。

    キャンセル

+2

Pythonでフォルダ内のファイルリストを取得する

考え方だけですがご参考までに。

・対象フォルダ配下のフルパスファイル名を全て取得したリストを作成する
・取得したリストを全ループで回す時にif文でフォルダ名\oldを含む場合は処理しない

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/27 19:25

    回答ありがとうございます!

    キャンセル

+1

参考として、old 以下を除外したファイル名表示するだけのコードを作ってみました。
a.py

import glob

for file in glob.iglob("./textdir/**/*.txt", recursive=True):
    if not file.startswith("./textdir/old/"):
        print("     ", file)
    else:
        print("skip ", file)


実行例:
イメージ説明

参考情報

...
Python3.3までは、 「あるディレクトリ以下に存在するテキストファイルの一覧を取得して、それぞれを開く」 という処理に、以下の3つのライブラリを使う必要がありました。

ファイルパス操作
os.path
ファイルの一覧取得
glob.glob
ファイルを開く
open
しかし、Python3.4以降であれば、これらを すべて 標準ライブラリpathlibに一任 することができます。
...

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/29 11:54

    回答ありがとうございます!
    いただいたコードを実行してみたところなぜかC.txtがスキップされない結果になってしまいました。フォルダ構成も同じにしているのですが。
    ./textdir\A.txt
    ./textdir\B.txt
    ./textdir\old\C.txt
    ./textdir\sub\D.txt

    キャンセル

  • 2018/09/29 12:02

    windows では ファイルの区切りが \ (バックスラッシュ)です。 私の環境は Mac なのでファイルの区切りは / です。
    https://www.python-izm.com/advanced/separator/ などを参考にしてみてください。
    "python ファイル セパレータ" で google 検索もしてみてください。

    キャンセル

  • 2018/09/30 11:35

    ./textdir/old/".replace('/', os.sep)のようにしたところ上手くいきました。
    ありがとうございます。

    キャンセル

  • 2018/09/30 11:50

    キャンセル

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

  • ただいまの回答率 90.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る