Начиная с (обратите внимание на подстановочные знаки до и после «некоторый текст»)
find . -type f -name '*some text*'
, как можно исключить / игнорировать все скрытые файлы и каталоги?
Я уже слишком долго гуглял , натолкнулся на какой-то идиот и! (восклицательный знак) параметров, но не подходит (и экономно) пример , который только что работал .
Трубопроводы |
- grep
были бы вариантом, и я также приветствовал бы примеры этого; но в первую очередь меня интересует краткая однострочная (или пара отдельных однострочных, иллюстрирующих различные способы достижения одной и той же цели командной строки) просто с использованием find
.
PS: Найти файлы в Linux и исключить конкретные каталоги кажется тесно связанным, но а) еще не принято и б) связано, но отличается и отличается, но в) может дать вдохновение и помогите определить путаницу!
Редактировать
find . \( ! -regex '.*/\..*' \) -type f -name "whatever"
, работает. Регулярное выражение ищет «что-нибудь, затем косую черту, затем точку, затем что-нибудь» (т. Е. Все скрытые файлы и папки, включая их подпапки) и «!» отрицает регулярное выражение.
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)
Исключает все скрытые каталоги и скрытые файлы в $ DIR
.Это одно из немногих средств исключения точечных файлов, которое также корректно работает в BSD, Mac и Linux:
find "$PWD" -name ".*" -prune -o -print
$PWD
выводит полный путь к текущему каталогу, поэтому что путь не начинается с ./
-name ".*" -prune
соответствует любым файлам или каталогам, которые начинаются с точки и затем не спускаются -o -print
означает печать имени файла, если предыдущее выражение не соответствовало ничему. Использование -print
или -print0
приводит к тому, что все остальные выражения не печатаются по умолчанию. @Flimm ответ хорош, особенно, потому что он предотвращает, находят от убывания в скрытые каталоги . Я предпочитаю это упрощение:
Обычно для исключения всех скрытых путей (регулярные файлы, каталоги, и т.д.):
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
только для каталогов, и поэтому только каталоги сокращены.
Вам не нужно использовать find
для этого. Просто используйте globstar в самой оболочке, например:
echo **/*foo*
или:
ls **/*foo*
где **/
представляет любую папку рекурсивно и *foo*
любой файл, имеющий foo
в его названии.
По умолчанию при использовании ls
печатаются имена файлов, исключая скрытые файлы и каталоги.
Если вы не включили глобирование, сделайте это с помощью shopt -s globstar
.
Примечание: Новая опция сглаживания работает в Bash 4, zsh и аналогичных оболочках. Sup>
Пример:
$ 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
Ответ , который я первоначально разместил как «правку» на мой оригинальный вопрос выше: sup>
find . \( ! -regex '.*/\..*' \) -type f -name "whatever"
, работает. Регулярное выражение ищет «что-нибудь, затем косую черту, затем точку, затем что-нибудь» (т. Е. Все скрытые файлы и папки, включая их подпапки) и «!» отрицает регулярное выражение.
Это печатает все файлы, которые являются потомками вашего каталога, пропуская скрытые файлы и каталоги:
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
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 ".*" \)
, чтобы найти те имена файлов, которые соответствуют обоим условиям - имя файла с 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' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2
Примечания:
.
: текущая папка -maxdepth 1
для поиска рекурсивно -type f
: найдите файлы, не каталоги (d
) -not -path '*/\.*'
: не возвращайтесь .hidden_files
sed 's/^\.\///g'
: удалите предварительно ожидаемый ./
из списка результата Этот ответ на аналогичный вопрос является единственным, который дал мне те же результаты, которые я получил бы, если бы я зашел в каждую папку, а затем сделал лс
. Мне пришлось добавить -типа f
для полноценной работы.
find . -not -path '*/\.*' -type f
Вариант на https://askubuntu.com/a/749708/321070
find -name '.?*' -prune -o -print
Вместо того, чтобы указывать полный путь к каталогу, вместо этого отфильтруйте вещи, которые соответствуют ch .?*
- буквенная точка, любой символ, а затем 0 или более символов.