14

ディレクトリへの絶対パスを使用してディレクトリをフィルタリングする方法はありますか?

shutil.copytree(directory,
                target_dir,
                ignore = shutil.ignore_patterns("/Full/Path/To/aDir/Common")) 

「」の下にある「共通」ディレクトリをフィルタリングしようとすると、これは機能しないようですaDir。私がこれを行う場合:

shutil.copytree(directory,
                target_dir,
                ignore = shutil.ignore_patterns("Common"))

それは機能しますが、Commonと呼ばれるすべてのディレクトリは、その「ツリー」でフィルタリングされます。これは、私が望むものではありません。

助言がありますか ?

ありがとう。

4

4 に答える 4

16

独自の無視関数を作成できます。

shutil.copytree('/Full/Path', 'target',
              ignore=lambda directory, contents: ['Common'] if directory == '/Full/Path/To/aDir' else [])

copytreeまたは、相対パスを使用して呼び出すことができるようにする場合:

import os.path
def ignorePath(path):
  def ignoref(directory, contents):
    return (f for f in contents if os.abspath(os.path.join(directory, f)) == path)
  return ignoref

shutil.copytree('Path', 'target', ignore=ignorePath('/Full/Path/To/aDir/Common'))

ドキュメントから:

無視が指定されている場合、copytree()によってアクセスされているディレクトリと、os.listdir()によって返されるその内容のリストを引数として受け取る呼び出し可能である必要があります。copytree()は再帰的に呼び出されるため、ignore callableは、コピーされるディレクトリごとに1回呼び出されます。呼び出し可能オブジェクトは、現在のディレクトリに関連する一連のディレクトリ名とファイル名(つまり、2番目の引数の項目のサブセット)を返す必要があります。これらの名前は、コピープロセスでは無視されます。ignore_patterns()を使用して、globスタイルのパターンに基づいて名前を無視する呼び出し可能オブジェクトを作成できます。

于 2011-10-20T21:01:46.227 に答える
4

shutil.ignore_patterns()のAPIは絶対パスをサポートしていませんが、独自のバリアントをロールするのは簡単です。

出発点として、*ignore_patterns*のソースコードを見てください。

def ignore_patterns(*patterns):
    """Function that can be used as copytree() ignore parameter.

    Patterns is a sequence of glob-style patterns
    that are used to exclude files"""
    def _ignore_patterns(path, names):
        ignored_names = []
        for pattern in patterns:
            ignored_names.extend(fnmatch.filter(names, pattern))
        return set(ignored_names)
    return _ignore_patterns

パスと名前のリストを受け入れる関数を返し、無視する名前のセットを返すことがわかります。ユースケースをサポートするには、パス引数を利用する独自の同様の関数を作成します。copytree()の呼び出しで関数をignoreパラメーターに渡します。

または、 shutilをそのまま使用しないでください。ソースコードは短くて甘いので、切り取り、貼り付け、カスタマイズは難しくありません。

于 2011-10-20T21:03:30.907 に答える
3

独自のignore関数を作成することをお勧めします。この関数は、処理中の現在のディレクトリをチェックし、ディレクトリが「/ Full / Path / To/aDir」の場合にのみ「Common」を含むリストを返します。

def ignore_full_path_common(dir, files):
    if dir == '/Full/Path/To/aDir':
        return ['Common']
    return []

shutil.copytree(directory, target_dir, ignore=ignore_full_path_common)
于 2011-10-20T21:07:37.557 に答える
0

答えてくれてありがとう。ignore_patterns()少し異なる要件に合わせて独自の関数を設計するのに役立ちました。ここにコードを貼り付けると、誰かに役立つかもしれません。

以下はignore_patterns()、絶対パスを使用して複数のファイル/ディレクトリを除外するための関数です。

myExclusionList->コピー中に除外されるファイル/ディレクトリを含むリスト。このリストには、ワイルドカードパターンを含めることができます。リスト内のパスは、srcpath提供されたものに関連しています。例:

[除外リスト]

java/app/src/main/webapp/WEB-INF/lib/test
unittests
python-buildreqs/apps/abc.tar.gz
3rd-party/jdk*

コードは下に貼り付けられます

def copydir(srcpath, dstpath, myExclusionList, log):

    patternlist = []
    try:
        # Forming the absolute path of files/directories to be excluded
        for pattern in myExclusionList:
            tmpsrcpath = join(srcpath, pattern)
            patternlist.extend(glob.glob(tmpsrcpath)) # myExclusionList can contain wildcard pattern hence glob is used
        copytree(srcpath, dstpath, ignore=ignore_patterns_override(*patternlist))
    except (IOError, os.error) as why:
        log.warning("Unable to copy %s to %s because %s", srcpath, dstpath, str(why))
        # catch the Error from the recursive copytree so that we can
        # continue with other files
    except Error as err:
        log.warning("Unable to copy %s to %s because %s", srcpath, dstpath, str(err))


# [START: Ignore Patterns]
# Modified Function to ignore patterns while copying.
# Default Python Implementation does not exclude absolute path
# given for files/directories

def ignore_patterns_override(*patterns):
    """Function that can be used as copytree() ignore parameter.
    Patterns is a sequence of glob-style patterns
    that are used to exclude files/directories"""
    def _ignore_patterns(path, names):
        ignored_names = []
        for f in names:
            for pattern in patterns:
                if os.path.abspath(join(path, f)) == pattern:
                    ignored_names.append(f)
        return set(ignored_names)
    return _ignore_patterns

# [END: Ignore Patterns]
于 2021-02-18T17:10:33.343 に答える