Как исключить / игнорировать скрытые файлы и каталоги в подстановоченном шаблоне & ldquo; find & rdquo; поиск?

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

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

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

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

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

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

подстановочные знаки до и после

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

1
задан 13 April 2017 в 15:24

5 ответов

Это печатает все файлы, которые являются потомками вашего каталога, пропуская скрытые файлы и каталоги:

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

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

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

Объяснение:

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

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

 find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*some text*' -print
102
ответ дан 25 May 2018 в 00:39
  • 1
    Обратите внимание, что последнее, что вам нужно, -print в конце! Кроме того, не уверен, что -name '\.*' would be more efficient instead of -path` (потому что путь ищет подпапки, но они будут обрезаны) – artfulrobot 29 April 2014 в 16:18
  • 2
    Каково особое значение . в этом контексте? – frostschutz 15 January 2015 в 19:40
  • 3
    @frostschutz Точка после find означает текущий каталог: find будет смотреть на все файлы и каталоги в текущем каталоге. Аргумент, следующий за path, является регулярным выражением, где точка обычно означает «любой символ», чтобы это означало буквальную точку, которую мы должны избегать с обратной косой чертой. Аргумент после -name не является регулярным выражением, но он расширяет подстановочные символы, такие как ? и *, как это делает оболочка. – Flimm 15 January 2015 в 21:23
  • 4
    @frostschutz На самом деле, подумайте об этом, я могу ошибаться в отношении ., имеющего особый смысл. – Flimm 5 August 2016 в 16:00
  • 5
    @Flimm yup, не нужно бежать .. Насколько мне известно, нужно избегать только этих: *, ? и []. – thdoan 15 February 2017 в 13:16

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

find "$PWD" -name ".*" -prune -o -print
$PWD печатать полный путь к текущему каталогу, чтобы путь не начинается с ./ -name ".*" -prune соответствует любым файлам или каталогам, начинающимся с точки, а затем не спускаться -o -print означает печать имени файла, если предыдущее выражение ничего не соответствовало. Использование -print или -print0 приводит к тому, что все остальные выражения не печатаются по умолчанию.
6
ответ дан 25 May 2018 в 00:39
  • 1
    Пожалуйста, объясните / уточните «тревожно сложный»; ответы уже даны, и ваш ответ, похоже, свидетельствует об обратном ...? – nutty about natty 25 March 2016 в 02:13
  • 2
    "тревожно сложный" вероятно, чрезмерен. Я переформулировал ответ, чтобы понять. Я думаю, что ответ, который я написал, трудно понять, и его трудно увидеть, не очень внимательно прочитав страницу руководства. Если вы только , используя GNU find, то есть более возможные решения. – eradman 28 March 2016 в 17:50
  • 3
    -o ... -print полезен. Для моего использования у меня теперь есть find ... '!' -name . -name '.*' -prune -o ... -print, что было более удобно, чем включение $ PWD. – Roger Pate 24 August 2016 в 22:28
  • 4
    $ PWD, вероятно, следует указывать, если в нем есть место. – Daniel James 19 April 2017 в 14:37
  • 5
    @ Даниэль Джеймс действительно, $PWD должен быть указан – eradman 19 April 2017 в 17:31
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)

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

4
ответ дан 25 May 2018 в 00:39
  • 1
    Это идеальный ответ. Он рекурсивно находит все файлы, но исключает позиции для каталогов и скрытых файлов. Благодаря! – KyleFarris 8 October 2015 в 08:41

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

echo **/*foo*

или:

ls **/*foo*

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

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

Если у вас нет включенного доступа, сделайте это с помощью .

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

Пример:

$ mkdir -vp a/b/c/d
mkdir: 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
3
ответ дан 25 May 2018 в 00:39
  • 1
    Вам не нужно ls для этого! [F2] – Kevin Cox 1 March 2016 в 07:25
  • 2
    @kenorb (и @ kevin-cox). Не могли бы вы быть немного более подробными? Почему здесь работает globstar (= *) и как? Что делает слэш / делать? – nutty about natty 18 May 2017 в 22:47
  • 3
    @nuttyaboutnatty / означает папку, она отделяет каталоги от имени файла. * в основном представляет все. – kenorb 18 May 2017 в 23:14
  • 4
    @kenorb yes-but: как этот однострочный шрифт помогает с исходным вопросом? – nutty about natty 19 May 2017 в 17:17
  • 5
    @nuttyaboutnatty Уточненный и добавленный пример. Это помогает найти файлы, игнорирующие скрытые. – kenorb 19 May 2017 в 19:40

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

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

1
ответ дан 25 May 2018 в 00:39

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

Похожие вопросы: