Есть ли способ, чтобы glob() только файлы?

Я знаю это glob может искать все файлы или только все каталоги внутри папки:

echo "All files:\n";
$all = glob("/*");
var_dump($all);

echo "Only directories\n";
$dirs = glob("/*", GLOB_ONLYDIR);
var_dump($dirs);

Но я не нашел что-то, чтобы эффективно находить только файлы в одной строке.

$files = array_diff(glob("/*"), glob("/*", GLOB_ONLYDIR));

Работает хорошо, но читает каталог дважды (даже если есть некоторые оптимизации, которые ускоряют второй просмотр).

8 ответов

Решение

Я наконец нашел решение:

echo "Only files\n";
$files = array_filter(glob("/*"), 'is_file');
var_dump($files);

Но будьте осторожны, array_filter сохранит числовые ключи: используйте array_values, если вам нужно переиндексировать массив.

Есть более простой способ, всего одна строка:

$files = glob("/path/to/directory/*.{*}", GLOB_BRACE);

{*} означает все окончания файлов, поэтому каждый файл, но без папки!

Ты можешь использовать GLOB_BRACE сопоставить документы со списком известных расширений файлов:

$files = glob("/path/to/directory/*.{jpg,gif,png,html,htm,php,ini}", GLOB_BRACE);

см.: http://www.electrictoolbox.com/php-glob-find-files/

Другое решение:

$files = glob('../{,.}*', GLOB_BRACE);
foreach ($files as $i => $file) {
    if (is_dir($file)) {
        unset($files[$i]);
    }
}

Или же:

$files = glob('../{,.}*', GLOB_BRACE | GLOB_MARK);
foreach ($files as $i => $file) {
    if ($file[ strlen($file) - 1 ] == '/') {
        unset($files[$i]);
    }
}

Оба сохраняют цифровые ключи, так что вы, возможно, захотите переиндексировать.

PS Вы должны использовать{,.}*', GLOB_BRACE если вы хотите получить скрытые файлы тоже.

Обратное регулярное выражение выполняет свою работу.

      preg_grep(
    ';^.*(\\\\|/)$;',
    glob("/*", GLOB_MARK),
    PREG_GREP_INVERT
);

\\\\ означает обратную косую черту Windows 🤯🔫

      function glob_file_only($path){
    return array_filter(glob($path,GLOB_MARK),function($file){
        return substr($file,-1)!=DIRECTORY_SEPARATOR;
    });
}

Это основано на работе других, которые ответили. Он касается каталога только один раз, а не два, и работает как для Windows, так и для Linux.

Это сработало для меня. если это кому поможет.

      for file_name in glob.glob('**/*', recursive=True):
    # we get all files and dirs
    if os.path.isfile(file_name):
        # we have only the files
$all = glob("/*.*");

это перечислит все с "." после имени файла. так что в основном все файлы.

Другие вопросы по тегам