Как исключить /игнорировать скрытые файлы и каталоги во встроенном подстановочном знаке поиска "найти"?

Начиная с (обратите внимание на подстановочные знаки до и после "немного текста")

find . -type f -name '*some text*'

как можно исключить / игнорировать все скрытые файлы и каталоги?

Я уже слишком долго гуглил, наткнулся на некоторые параметры -prune и ! (восклицательный знак), но не нашел подходящего (и экономного) примера который только что сработал.

Трубопроводный | к grep это был бы вариант, и я также приветствовал бы примеры этого; но преимущественно Меня интересует краткий однострочник (или пара отдельных однострочников, иллюстрирующих различные способы достижения одной и той же цели командной строки) просто с помощью find.

пс: Поиск файлов в Linux и исключение определенных каталогов кажется тесно связанным, но а) еще не принято, и б) связано, но отличается и отличается, но в) может послужить источником вдохновения и помочь выявить путаницу!

Редактировать

find . \( ! -regex '.*/\..*' \) -type f -name "whatever", работает. Регулярное выражение ищет "что угодно, затем косую черту, затем точку, затем что угодно" (т.е. все скрытые файлы и папки, включая их вложенные папки), а "!" отменяет регулярное выражение.

При этом будут выведены все файлы, являющиеся потомками вашего каталога, пропуская скрытые файлы и каталоги:

find . -not -path '*/\.*'

Так что, если вы ищете файл с some text в его названии, и вы хотите пропустить скрытые файлы и каталоги, запустите:

find . -not -path '*/\.*' -type f -name '*some text*'

Объяснение:

То -path опция runs проверяет шаблон на соответствие всей строке пути. * является подстановочным знаком, / является разделителем каталогов, \. является точкой (она должна быть экранирована, чтобы избежать особого значения), и * это еще один подстановочный знак. -not означает, что не выбирайте файлы, соответствующие этому тесту.

Я не думаю, что find достаточно умен, чтобы избежать рекурсивного поиска скрытых каталогов в предыдущей команде, поэтому, если вам нужна скорость, используйте -prune вместо этого, вот так:

 find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*some text*' -print

Это одно из немногих средств удаления точечных файлов, которое также корректно работает на BSD, Mac и Linux:

find "$PWD" -name ".*" -prune -o -print
  • $PWD выведите полный путь к текущему каталогу, чтобы путь не начинался с ./
  • -name ".*" -prune соответствует любым файлам или каталогам, которые начинаются с точки, а затем не опускаются
  • -o -print означает вывод имени файла, если предыдущее выражение ничему не соответствовало. С помощью -print или -print0 приводит к тому, что все остальные выражения по умолчанию не печатаются.
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)

Исключает все скрытые каталоги и скрытые файлы под $DIR

Вам не нужно использовать find за это. Просто используйте globstar в самостоятельной оболочке, например:

echo **/*foo*

или:

ls **/*foo*

где **/ представляет любую папку рекурсивно и *foo* любой файл, который имеет foo в его названии.

По умолчанию используется ls будут выведены имена файлов, за исключением скрытых файлов и каталогов.

Если у вас не включена глобализация, сделайте это с помощью shopt -s globstar.

Примечание: Новая опция масштабирования работает в Bash 4, zsh и подобных оболочках.


Пример:

$ mkdir -vp a/b/c/dmkdir: created directory 'a'mkdir: created directory 'a/b'mkdir: created directory 'a/b/c'mkdir: created directory 'a/b/c/d'$ touch a/b/c/d/foo a/b/c/d/bar  a/b/c/d/.foo_hidden a/b/c/d/foo_not_hidden$ echo **/*foo*a/b/c/d/foo  a/b/c/d/foo_not_hidden

То ответ Первоначально я опубликовал в качестве "редактирования" свой первоначальный вопрос выше:

find . \( ! -regex '.*/\..*' \) -type f -name "whatever", работает. Регулярное выражение ищет "что угодно, затем косую черту, затем точку, затем что угодно" (т.е. все скрытые файлы и папки, включая их вложенные папки), а "!" отменяет регулярное выражение.

Обычно это тоже работает

find * [expression]

Используя подстановочный знак * shell для ввода всех путей из рабочего каталога, обычно подстановочный знак * не распространяется на скрытые файлы, но это можно изменить в настройках оболочки.Пример:

find /path/* -iname file -mtime -3

@Flimm's ответ это хорошо, особенно потому, что это предотвращает переход поиска в скрытые каталоги. Я предпочитаю это упрощение:

Как правило, чтобы исключить все скрытые пути (обычные файлы, каталоги и т.д.):

find <start-point> -path '*/.*' -prune -o <expression> -print

Например, используя свой рабочий каталог в качестве начальной точки, и -name '*some text*' как выражение:

find . -path '*/.*' -prune -o -name '*some text*' -print

В отличие от того, что предполагает ответ @ Flimm, отсутствие скрытых файлов или скрытых каталогов - это простой случай. То -path '*/.*' выражение истинно для любого пути (обычных файлов, каталогов и т.д.), Который имеет . сразу после вашего разделителя файлов, /. Таким образом, эта строка удалит как скрытые файлы, так и каталоги.

Разрешение скрытых файлов при исключении скрытых каталогов - это тот случай, когда требуется дополнительный фильтр. Это то место, где вы бы включили -type d в сокращаемом выражении.

find <start-point> -type d -path '*/.*' -prune -o <expression> -print 

Например:

find . -type d -path '*/.*' -prune -o -name '*some text*' -print

В этом случае -type d -path '*/.*' является true только для каталогов, и поэтому обрезаются только каталоги.

Вариант на https://askubuntu.com/a/749708/321070

find  -name '.?*' -prune -o -print

Вместо того, чтобы указывать полный путь к каталогу, вместо этого отфильтруйте то, что имеет значение. .?* - буквальная точка, любой символ, а затем 0 или более символов.

find имеет аккуратные логические переключатели, такие как -and и -not вы можете использовать их в своих интересах, чтобы найти соответствующий файл с двумя правилами, например:

$ touch non_hidden_file.txt .hidden_file.txt somethings/.another_hidden_file.txt                                                 $ find . -type f -name '*hidden_file*' -and \( -not -name ".*" \)                            ./non_hidden_file.txt

Как вы можете видеть, find использует два правила -name '*hidden_file*' и -and \( -not -name ".*" \) чтобы найти те имена файлов, которые соответствуют обоим условиям - filename с hidden_file в нем, но без ведущей точки. Обратите внимание на косые черты перед круглыми скобками - они используются для определения круглых скобок как find аргументы, скорее определяющие подоболочку (что в противном случае означает круглые скобки без косых черт)

$ pwd/home/victoria$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort/home/victoria/new/home/victoria/new1/home/victoria/new2/home/victoria/new3/home/victoria/new3.md/home/victoria/new.md/home/victoria/package.json/home/victoria/Untitled Document 1/home/victoria/Untitled Document 2$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sortnewnew1new2new3new3.mdnew.mdpackage.jsonUntitled Document 1Untitled Document 2

Записи:

  • . : текущая папка
  • удалить -maxdepth 1 для рекурсивного поиска
  • -type f : поиск файлов, а не каталогов (d)
  • -not -path '*/\.*' : не возвращайте .hidden_files
  • sed 's/^\.\///g' : удалите добавленный ./ из списка результатов

По теме: Исключить скрытые файлы при поиске с помощью Unix/Linux find?

Не помогает с тем, что вы спросили в своей правке, но взгляните на мой вопрос и его ответ здесь: Can this find command be made more compact? - Unix & Linux Stack Exchange а также ссылка в ответе.