{
    "content": [
        {
            "type": "text",
            "text": "# File::Find (perldoc)\n\n## NAME\n\nFile::Find - Traverse a directory tree.\n\n## SYNOPSIS\n\nuse File::Find;\nfind(\\&wanted, @directoriestosearch);\nsub wanted { ... }\nuse File::Find;\nfinddepth(\\&wanted, @directoriestosearch);\nsub wanted { ... }\nuse File::Find;\nfind({ wanted => \\&process, follow => 1 }, '.');\n\n## DESCRIPTION\n\nThese are functions for searching through directory trees doing work on each file found similar\nto the Unix *find* command. File::Find exports two functions, \"find\" and \"finddepth\". They work\nsimilarly but have subtle differences.\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION** (1 subsections)\n- **WARNINGS**\n- **BUGS AND CAVEATS**\n- **HISTORY**\n- **SEE ALSO** (1 subsections)\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "File::Find",
        "section": "",
        "mode": "perldoc",
        "summary": "File::Find - Traverse a directory tree.",
        "synopsis": "use File::Find;\nfind(\\&wanted, @directoriestosearch);\nsub wanted { ... }\nuse File::Find;\nfinddepth(\\&wanted, @directoriestosearch);\nsub wanted { ... }\nuse File::Find;\nfind({ wanted => \\&process, follow => 1 }, '.');",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 11,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 120,
                "subsections": [
                    {
                        "name": "The wanted function",
                        "lines": 78
                    }
                ]
            },
            {
                "name": "WARNINGS",
                "lines": 8,
                "subsections": []
            },
            {
                "name": "BUGS AND CAVEATS",
                "lines": 17,
                "subsections": []
            },
            {
                "name": "HISTORY",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "SEE ALSO",
                "lines": 1,
                "subsections": [
                    {
                        "name": "find",
                        "lines": 1
                    }
                ]
            }
        ],
        "sections": {
            "NAME": {
                "content": "File::Find - Traverse a directory tree.\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use File::Find;\nfind(\\&wanted, @directoriestosearch);\nsub wanted { ... }\n\nuse File::Find;\nfinddepth(\\&wanted, @directoriestosearch);\nsub wanted { ... }\n\nuse File::Find;\nfind({ wanted => \\&process, follow => 1 }, '.');\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "These are functions for searching through directory trees doing work on each file found similar\nto the Unix *find* command. File::Find exports two functions, \"find\" and \"finddepth\". They work\nsimilarly but have subtle differences.\n\nfind\nfind(\\&wanted,  @directories);\nfind(\\%options, @directories);\n\n\"find()\" does a depth-first search over the given @directories in the order they are given.\nFor each file or directory found, it calls the &wanted subroutine. (See below for details on\nhow to use the &wanted function). Additionally, for each directory found, it will \"chdir()\"\ninto that directory and continue the search, invoking the &wanted function on each file or\nsubdirectory in the directory.\n\nfinddepth\nfinddepth(\\&wanted,  @directories);\nfinddepth(\\%options, @directories);\n\n\"finddepth()\" works just like \"find()\" except that it invokes the &wanted function for a\ndirectory *after* invoking it for the directory's contents. It does a postorder traversal\ninstead of a preorder traversal, working from the bottom of the directory tree up where\n\"find()\" works from the top of the tree down.\n\nDespite the name of the \"finddepth()\" function, both \"find()\" and \"finddepth()\" perform a\ndepth-first search of the directory hierarchy.\n\n%options\nThe first argument to \"find()\" is either a code reference to your &wanted function, or a hash\nreference describing the operations to be performed for each file. The code reference is\ndescribed in \"The wanted function\" below.\n\nHere are the possible keys for the hash:\n\n\"wanted\"\nThe value should be a code reference. This code reference is described in \"The wanted\nfunction\" below. The &wanted subroutine is mandatory.\n\n\"bydepth\"\nReports the name of a directory only AFTER all its entries have been reported. Entry point\n\"finddepth()\" is a shortcut for specifying \"{ bydepth => 1 }\" in the first argument of\n\"find()\".\n\n\"preprocess\"\nThe value should be a code reference. This code reference is used to preprocess the current\ndirectory. The name of the currently processed directory is in $File::Find::dir. Your\npreprocessing function is called after \"readdir()\", but before the loop that calls the\n\"wanted()\" function. It is called with a list of strings (actually file/directory names) and\nis expected to return a list of strings. The code can be used to sort the file/directory\nnames alphabetically, numerically, or to filter out directory entries based on their name\nalone. When *follow* or *followfast* are in effect, \"preprocess\" is a no-op.\n\n\"postprocess\"\nThe value should be a code reference. It is invoked just before leaving the currently\nprocessed directory. It is called in void context with no arguments. The name of the current\ndirectory is in $File::Find::dir. This hook is handy for summarizing a directory, such as\ncalculating its disk usage. When *follow* or *followfast* are in effect, \"postprocess\" is a\nno-op.\n\n\"follow\"\nCauses symbolic links to be followed. Since directory trees with symbolic links (followed)\nmay contain files more than once and may even have cycles, a hash has to be built up with an\nentry for each file. This might be expensive both in space and time for a large directory\ntree. See \"followfast\" and \"followskip\" below. If either *follow* or *followfast* is in\neffect:\n\n*   It is guaranteed that an *lstat* has been called before the user's \"wanted()\" function\nis called. This enables fast file checks involving \"\". Note that this guarantee no\nlonger holds if *follow* or *followfast* are not set.\n\n*   There is a variable $File::Find::fullname which holds the absolute pathname of the file\nwith all symbolic links resolved. If the link is a dangling symbolic link, then fullname\nwill be set to \"undef\".\n\nThis is a no-op on Win32.\n\n\"followfast\"\nThis is similar to *follow* except that it may report some files more than once. It does\ndetect cycles, however. Since only symbolic links have to be hashed, this is much cheaper\nboth in space and time. If processing a file more than once (by the user's \"wanted()\"\nfunction) is worse than just taking time, the option *follow* should be used.\n\nThis is also a no-op on Win32.\n\n\"followskip\"\n\"followskip==1\", which is the default, causes all files which are neither directories nor\nsymbolic links to be ignored if they are about to be processed a second time. If a directory\nor a symbolic link are about to be processed a second time, File::Find dies.\n\n\"followskip==0\" causes File::Find to die if any file is about to be processed a second\ntime.\n\n\"followskip==2\" causes File::Find to ignore any duplicate files and directories but to\nproceed normally otherwise.\n\n\"danglingsymlinks\"\nSpecifies what to do with symbolic links whose target doesn't exist. If true and a code\nreference, will be called with the symbolic link name and the directory it lives in as\narguments. Otherwise, if true and warnings are on, a warning of the form\n\"\"symboliclinkname is a dangling symbolic link\\n\"\" will be issued. If false, the dangling\nsymbolic link will be silently ignored.\n\n\"nochdir\"\nDoes not \"chdir()\" to each directory as it recurses. The \"wanted()\" function will need to be\naware of this, of course. In this case, $ will be the same as $File::Find::name.\n\n\"untaint\"\nIf find is used in taint-mode (-T command line switch or if EUID != UID or if EGID != GID),\nthen internally directory names have to be untainted before they can be \"chdir\"'d to.\nTherefore they are checked against a regular expression *untaintpattern*. Note that all\nnames passed to the user's \"wanted()\" function are still tainted. If this option is used\nwhile not in taint-mode, \"untaint\" is a no-op.\n\n\"untaintpattern\"\nSee above. This should be set using the \"qr\" quoting operator. The default is set to\n\"qr|^([-+@\\w./]+)$|\". Note that the parentheses are vital.\n\n\"untaintskip\"\nIf set, a directory which fails the *untaintpattern* is skipped, including all its\nsub-directories. The default is to \"die\" in such a case.\n",
                "subsections": [
                    {
                        "name": "The wanted function",
                        "content": "The \"wanted()\" function does whatever verifications you want on each file and directory. Note\nthat despite its name, the \"wanted()\" function is a generic callback function, and does not tell\nFile::Find if a file is \"wanted\" or not. In fact, its return value is ignored.\n\nThe wanted function takes no arguments but rather does its work through a collection of\nvariables.\n\n$File::Find::dir is the current directory name,\n$ is the current filename within that directory\n$File::Find::name is the complete pathname to the file.\n\nThe above variables have all been localized and may be changed without affecting data outside of\nthe wanted function.\n\nFor example, when examining the file /some/path/foo.ext you will have:\n\n$File::Find::dir  = /some/path/\n$                = foo.ext\n$File::Find::name = /some/path/foo.ext\n\nYou are chdir()'d to $File::Find::dir when the function is called, unless \"nochdir\" was\nspecified. Note that when changing to directories is in effect, the root directory (/) is a\nsomewhat special case inasmuch as the concatenation of $File::Find::dir, '/' and $ is not\nliterally equal to $File::Find::name. The table below summarizes all variants:\n\n$File::Find::name  $File::Find::dir  $\ndefault      /                  /                 .\nnochdir=>0  /etc               /                 etc\n/etc/x             /etc              x\n\nnochdir=>1  /                  /                 /\n/etc               /                 /etc\n/etc/x             /etc              /etc/x\n\nWhen \"follow\" or \"followfast\" are in effect, there is also a $File::Find::fullname. The\nfunction may set $File::Find::prune to prune the tree unless \"bydepth\" was specified. Unless\n\"follow\" or \"followfast\" is specified, for compatibility reasons (find.pl, find2perl) there are\nin addition the following globals available: $File::Find::topdir, $File::Find::topdev,\n$File::Find::topino, $File::Find::topmode and $File::Find::topnlink.\n\nThis library is useful for the \"find2perl\" tool (distributed as part of the App-find2perl CPAN\ndistribution), which when fed,\n\nfind2perl / -name .nfs\\* -mtime +7 \\\n-exec rm -f {} \\; -o -fstype nfs -prune\n\nproduces something like:\n\nsub wanted {\n/^\\.nfs.*\\z/s &&\n(($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($)) &&\nint(-M ) > 7 &&\nunlink($)\n||\n($nlink || (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($))) &&\n$dev < 0 &&\n($File::Find::prune = 1);\n}\n\nNotice the \"\" in the above \"int(-M )\": the \"\" is a magical filehandle that caches the\ninformation from the preceding \"stat()\", \"lstat()\", or filetest.\n\nHere's another interesting wanted function. It will find all symbolic links that don't resolve:\n\nsub wanted {\n-l && !-e && print \"bogus link: $File::Find::name\\n\";\n}\n\nNote that you may mix directories and (non-directory) files in the list of directories to be\nsearched by the \"wanted()\" function.\n\nfind(\\&wanted, \"./foo\", \"./bar\", \"./baz/epsilon\");\n\nIn the example above, no file in ./baz/ other than ./baz/epsilon will be evaluated by\n\"wanted()\".\n\nSee also the script \"pfind\" on CPAN for a nice application of this module.\n"
                    }
                ]
            },
            "WARNINGS": {
                "content": "If you run your program with the \"-w\" switch, or if you use the \"warnings\" pragma, File::Find\nwill report warnings for several weird situations. You can disable these warnings by putting the\nstatement\n\nno warnings 'File::Find';\n\nin the appropriate scope. See warnings for more info about lexical warnings.\n",
                "subsections": []
            },
            "BUGS AND CAVEATS": {
                "content": "$dontusenlink\nYou can set the variable $File::Find::dontusenlink to 0 if you are sure the filesystem you\nare scanning reflects the number of subdirectories in the parent directory's \"nlink\" count.\n\nIf you do set $File::Find::dontusenlink to 0, you may notice an improvement in speed at\nthe risk of not recursing into subdirectories if a filesystem doesn't populate \"nlink\" as\nexpected.\n\n$File::Find::dontusenlink now defaults to 1 on all platforms.\n\nsymlinks\nBe aware that the option to follow symbolic links can be dangerous. Depending on the\nstructure of the directory tree (including symbolic links to directories) you might traverse\na given (physical) directory more than once (only if \"followfast\" is in effect).\nFurthermore, deleting or changing files in a symbolically linked directory might cause very\nunpleasant surprises, since you delete or change files in an unknown directory.\n",
                "subsections": []
            },
            "HISTORY": {
                "content": "File::Find used to produce incorrect results if called recursively. During the development of\nperl 5.8 this bug was fixed. The first fixed version of File::Find was 1.01.\n",
                "subsections": []
            },
            "SEE ALSO": {
                "content": "",
                "subsections": [
                    {
                        "name": "find",
                        "content": ""
                    }
                ]
            }
        }
    }
}