Вопрос или проблема
Как я могу показать список всех не скрытых файлов в терминале Mac, используя команду find с относительным путем для директории патента в качестве параметра (т.е. ../../
)?
Я попробовал,
find ../../ -path "*/.*" -prune -o -type f -print
Также,
find ../../ -not -path "*/.*/*" -type f
Ни один из них не сработал. Ничего не показывается, хотя в директории есть не скрытые файлы и папки. Вероятно, потому что файлы рассматриваются как ../../unhidden_file
системой и затем считаются скрытыми. Есть ли какой-то умный обходной путь для этой проблемы?
-path "*/.*"
соответствует ../../
, поэтому он обрезает начальную точку (обрезает все дерево у корня)!
find ../.. -name '.*' ! -name .. -prune -o -type f -print
Обрезает все файлы или директории, имя которых начинается с .
, за исключением тех, которые называются ..
(что относится только к начальной точке ../..
, так как find
в противном случае не учитывает записи ..
или .
в любой директории, которую он находит во время обхода дерева директорий) и выводит путь к файлам типа обычных среди оставшихся.
Вы также можете сделать:
find ../.. ! -path ../.. -name '.*' -prune -o -type f -print
Чтобы более явно указать, что это начальное ../..
, которое вы не хотите обрезать, даже если оно имеет имя, начинающееся с .
.
Осторожно, на некоторых системах, -name '.*'
(и тем более -path '*/.*'
) может не соответствовать некоторым скрытым файлам, если то, что следует за .
, не делает допустимый текст в локали пользователя. На таких системах вам потребуется
LC_ALL=C find ../.. ! -path ../.. -name '.*' -prune -o -type f -print
Чтобы обойти это.
С реализацией find
в FreeBSD, на которой основана реализация в macos, вы также можете использовать:
find ../.. ! -depth 0 -name '.*' -prune -o -type f -print
Или:
find ../.. -depth +0 -name '.*' -prune -o -type f -print
Чтобы -prune
не выполнялось для файлов на глубине 0, то есть тех, которые переданы как аргументы файла в find
(здесь ../..
), независимо от того, начинается ли их имя с .
.
Если использовать оболочку zsh
, альтернативой использованию find
будет сделать:
print -rC1 ../../**/*(N.)
С использованием рекурсивных глобов zsh (где **/
соответствует любому уровню директорий), которые по умолчанию исключают скрытые файлы, и .
глобальный квалификатор как эквивалент -type f
в find
(и N
, чтобы не сообщать об ошибке, если нет совпадений).
В качестве дополнительного преимущества это дает вам отсортированный список (и вы можете изменить порядок с помощью глобальных квалификаторов o<criteria>
, O<criteria>
и/или n
).
.
Ответ или решение
Для решения проблемы отображения списка всех не скрытых файлов в терминале Mac, используя команду find
, важно понимать несколько ключевых моментов в работе поиска файлов в UNIX-системах, особенно на macOS. Давайте подробно разберем, как вы можете использовать команду find
, чтобы добиться желаемого результата, и какие нюансы необходимо учитывать.
Теория
Команда find
в UNIX-системах, включая macOS, является мощным инструментом для рекурсивного поиска файлов и каталогов, начиная с указанного исходного каталога. В случае, если вам нужно показать все несокрытые файлы, важно правильно использовать комбинации флагов и условий find
, чтобы минимизировать влияние скрытых файлов и каталогов. На macOS скрытые файлы и каталоги начинаются с точки (.
), что делает задачу более сложной при использовании стандартных подходов, поскольку начальные точки (.
и ..
) могут нежелательно влиять на вашу команду.
Примеры
Ваши попытки с командами find ../../ -path "*/.*" -prune -o -type f -print
и find ../../ -not -path "*/.*/*" -type f
не дали желаемого результата из-за особенностей обработки путей, содержащих начальные точки. Давайте рассмотрим несколько примеров, которые могут решить эту задачу.
-
Базовая логика исключения скрытых файлов:
find ../.. -name '.*' ! -name .. -prune -o -type f -print
Здесь используется логика, которая исключает файлы и каталоги, начинающиеся на точку, за исключением исходного каталога
../..
. Это ключевой момент, чтобы избежать исключения корневого каталога поиска. -
Уточненная команда для macOS:
find ../.. ! -path ../.. -name '.*' -prune -o -type f -print
Это делает явное исключение для начальной точки, чтобы убедиться, что не происходит исключение всего дерева с корнем в
../..
. -
Решение с учетом локали:
На некоторых системах может возникнуть проблема с интерпретацией имен файлов, если они не соответствуют текущей локали. В таких случаях помогает установка переменной окруженияLC_ALL
:LC_ALL=C find ../.. ! -path ../.. -name '.*' -prune -o -type f -print
Это гарантирует, что
find
корректно сопоставляет имена файлов независимо от настроек локали пользователя. -
Использование флагов глубины для FreeBSD find:
На macOS, которая основывается на FreeBSD, доступны полезные флаги для ограничения глубины:find ../.. ! -depth 0 -name '.*' -prune -o -type f -print
-
Альтернатива через Zsh:
Если вы используете оболочку Zsh, возможно более простое решение, используя рекурсивные шаблоны:print -rC1 ../../**/*(N.)
Этот метод использует особенность Zsh по умолчанию исключать скрытые файлы. Глобальный квалификатор
.
ограничивает поиск только файлами.
Применение
Вам следует выбирать подходящий метод в зависимости от ваших потребностей. Если вы работаете в системе с установленной Zsh оболочкой и не требуется строго использование find
, вы можете воспользоваться её мощными возможностями фильтрации. Тем не менее, знания и практические навыки работы с командой find
более универсальны и могут быть полезны в различных ситуациях, где Zsh недоступна или нежелательна.
В конечном счете, правильное понимание особенностей find
, таких как корректная интерпретация точек в путях и учет локальных настроек, обеспечит успешное выполнение задачи. Такой детализированный подход требует понимания тонкостей системных команд, что характеризует высококвалифицированного IT специалиста и помогает решать задачи эффективности и оптимизации процессов. Это также демонстрирует ваш проактивный подход в решении проблем, позволяющий выбрать наилучший инструмент для конкретной ситуации.