Я хочу, чтобы мой удар распечатал 'найденный', только если что-то найдено, с помощью команды находки. Но использование && не помогает: даже если найденный ничем, я становлюсь 'найденным' распечатанным. Пример:
$ pwd
/data/data/com.termux/files/home/test/test1/test4
$ ls
xaa xab
$ find . -name xac && echo 'found'
found
$ find . -name xaa && echo 'found'
./xaa
found
Можно сделать find
самостоятельно печать found
:
find . -name xac -printf "found\n" -quit
-quit
сделает find
выход после первого соответствия, таким образом, found
только печатается самое большее однажды.
На подобном потоке на Unix & Linux (делают, находят сбой, когда ничто не было найдено), я использовал grep -qz
возвратить ненулевой статус выхода если find
найденный ничем:
find /some/path -print0 -quit | grep -qz .
Который можно использовать для построения составного использования команд &&
или if
:
find /some/path -print0 -quit | grep -qz . && echo found
ответ muru является соответствующим и хорошо подходящим для случаев, где мы хотим распечатать что-то, если файл найден. Для общего случая, когда мы хотим выполнить внешнюю команду, такой как echo
, мы могли использовать -exec
флаг.
$ find . -name 'xac' -exec echo "I found " {} \; -quit
I found ./xac
{}
часть передает имя файла команде между -exec
и \;
как аргументы. Отметьте \
прежде ;
- это препятствует тому, чтобы оболочка неправильно истолковала it; в оболочке, заключительная точка с запятой показывает конец команды, но при выходе с наклонной чертой оболочка будет рассматривать его как литеральный текст, который будет передан find
команда и найти команду это служит закрытием -exec
аргументы флага.
Для построения условных выражений if found do this; else do that
вид, мы могли использовать команду substition $()
и test
команда (иначе [
):
$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"
not found
$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"
found
Обращение к комментарию Dan
Dan в комментариях спросил:
Не отозвался бы эхом "Я нашел {}" быть лучше, чем эхо, "Я нашел" {}? Возможно, для эха хорошо, но если кто-то копирует команду и заменяет эхо другой командой, у них может быть проблема
Давайте поймем проблему сначала. Обычно, в оболочках существует понятие разделения слова, что означает неупомянутые переменные, и позиционные параметры будут расширять и рассматривать как отдельные объекты. Например, если у Вас есть переменная var
и это содержит hello world
текст, когда Вы делаете touch $var
оболочка разломает его на два отдельных объекта hello
и world
и touch
поймет это, как будто Вы пытались создать 2 отдельных файла; если Вы делаете touch "$var"
, затем оболочка будет рассматривать hello world
как одна единица, и touch
создаст один файл только. Это важно, чтобы понять, что это происходит только из-за того, как работают оболочки.
В отличие от этого, find
не страдает от такого поведения, потому что команды обрабатываются find
самостоятельно и выполняемый execvp()
системный вызов, таким образом, нет никакой включенной оболочки. В то время как фигурные скобки действительно имеют особое значение в оболочках, потому что они появляются посреди find
команда, а не в начале, они не несут особого значения для окружения в этом случае. Вот пример. Давайте создадим несколько трудных имен файлов и попытаемся передать их как аргумент stat
команда.
$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt
$ find -type f -exec stat -c "%F" {} \; -print
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt
Как видете, stat
получает трудные имена файлов, превосходные с find
, который является одной из главных причин, почему рекомендуется для использования в портативных сценариях, и особенно полезное, когда Вы пересекаете дерево каталогов и хотите сделать что-то с именами файлов, которые могли бы потенциально иметь специальные символы в них. Поэтому не необходимо заключить фигурные скобки в кавычки для команд, выполняемых в find
.
Это - другая история, когда оболочка принимает участие. Иногда необходимо использовать оболочку для обработки имени файла. В этом случае заключение в кавычки будет действительно иметь значение, но важно понять, что это не проблема находки - это - оболочка, которая делает разделение слова.
$ find -type f -exec bash -c "stat {}" sh \;
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory
Таким образом, когда мы заключаем в кавычки в оболочке, она будет работать. Но снова, это важно для оболочки, нет find
.
$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;
regular empty file
regular empty file
regular empty file