Во-первых, не всегда верно, что стандартный ввод связан с клавиатурой. Во-вторых, вы не используете стандартный ввод для передачи чего-либо в echo
. Вы используете клавиатуру для передачи строки echo foo
в вашу оболочку. Оболочка анализирует эту строку и вызывает команду с именем echo
(, независимо от того, является ли команда встроенной в оболочку или исполняемым файлом /usr/bin/echo
или /bin/echo
не имеет значения ), которая анализирует свои аргументы, игнорирует свой стандартный ввод и записывает строкаfoo\n
Во-первых, обратите внимание, что -not
является расширением GNU и является эквивалентом стандартного оператора !
. Он практически не имеет преимуществ перед !
.
Предикат -prune
всегда оценивается как true и влияет на то, как find
проходит по дереву каталогов. Если файл, для которого запускается -prune
, имеет тип каталог (, возможно определенный после разрешения симлинков с помощью -L
/-H
/-follow
), то find
в него не спустится.
Таким образом,-name 'pattern' -prune
(сокращение от-name 'pattern' -a -prune
)такое же, как -name 'pattern'
, за исключением того, что каталоги, имя которых соответствует pattern
, будут сокращены , то есть find
не будут опускаться в них..
-name '.?*'
соответствует файлам, имя которых начинается с .
, за которым следует один символ (, определение которого зависит от текущей локали ), за которым следует 0 или более символов . Таким образом, это соответствует .
, за которым следует один или несколько символов (, чтобы не обрезать .
начальный каталог ).
Таким образом, это соответствует скрытым файлам с оговоркой, что оно соответствует только тем, имя которых также полностью состоит из символов , то есть является допустимым текстом в текущей локали (, по крайней мере, с реализацией GNU ).
Так вот,
find. \( -name '.?*' -a -prune \) -o -type f -a -print
То же, что и
find. -name '.?*' -prune -o -type f -print
поскольку И (-a
, подразумеваемый )имеет приоритет над ИЛИ(-o
).
находит файлы, которые являются обычными(без символической ссылки, каталога, fifo, устройства...)и не скрыты и не находятся в скрытых каталогах (при условии, что все пути к файлам являются допустимым текстом в локали ).
find. -type f -not -name '^.*'
Или его стандартный эквивалент:
find. -type f ! -name '^.*'
Будут найдены обычные файлы, имя которых не начинается с ^.
.
find. -type f ! -name '.*'
Найдет обычные файлы, имя которых не начинается с .
, но по-прежнему будет сообщать о файлах в скрытых каталогах.
find. -type f ! -path '*/.*'
Пропустит скрытые файлы и файлы в скрытых каталогах, но find
по-прежнему будет спускаться в скрытые каталоги (любого уровня глубины )только для пропуска всех файлов в них, поэтому менее эффективен, чем подход с использованием -prune
.
Предикат -prune
в find
удаляет ветвь дерева поиска. Следовательно, использование -prune
в качестве первой команды в вашем вопросе даст вам те же результаты, что и ваша вторая команда, только если в каталогах нет файлов со скрытыми именами.
Пример:
$ tree -a
.
|--.hiddendir
| `-- file
`-- dir
`-- file
2 directories, 2 files
$ find. \( -name '.?*' -prune \) -o -type f -print
./dir/file
$ find. -type f ! -name '.*'
./dir/file
./.hiddendir/file
(Я исправил тест -name
здесь, поскольку вы, кажется, используете бессмысленное регулярное выражение, и я использовал !
вместо нестандартного --not
).
Как видите, поскольку имя .hiddendir
соответствует шаблону подстановки .?*
, оно удаляется из дерева поиска с помощью первой команды, а файл file
под ним не найден.
Во второй команде каталог .hiddendir
не удаляется из дерева поиска, поэтому файл file
в нем найден.