Як виявити, чи знайшов "знайти" відповідність?


16

Чи є ідіоматичний засіб виявити, чи знайшов "знайти" які-небудь збіги? Я зараз використовую

COUNT=`find ... | wc -l`
if [ "$COUNT" -gt 0 ]; then

але це здається мені трохи непрямим. Також я хотів би зупинити пошук, коли знайдеться відповідність, тому це не витрачає часу і сил. Мені просто потрібно знати, чи є файли, які відповідають.

Оновлення: я допустив помилку, коли писав запитання без коду перед собою: я використовую wc -lв іншому випадку, де мені все одно потрібно знати загальну кількість знайдених файлів. У випадку, коли я лише перевіряю, чи є відповідники, я використовував if [ -z $(find …) ].

Відповіді:


17

Якщо ви знаєте, що у вас є GNU, знайдіть його, -quit щоб зупинити його після першого матчу.

Портабельная, труби вихід findв head -n 1. Цей спосіб findзагине від розбитої труби через кілька матчів (коли вона заповнена headвхідним буфером).

Так чи інакше, вам не потрібно wcперевіряти, чи рядок порожній, оболонка може робити це самостійно.

if [ -n "$(find … | head -n 1)" ]; then …

Цікаво ... Я думав, що -nзастосовується лише до 'визначених' змінних ($ abc, $ xyz тощо), але я вважаю, що $ (...) є 'визначеною' temp змінною .. +1 ... (і я просто нещодавно прочитайте, що використовувати -nризиковано, якщо ви не впевнені, що змінна ще не була оголошена і не використовується, але темп не матиме такої можливості ... тобто. неініціалізований проти порожнього
Пітер.O

2
@fred: Навпаки, -nтестує, чи рядок порожній, він не має нічого спільного зі змінними. Те, що ви читали, напевно, говорило, що використання -nне перевіряє, чи визначена змінна: -n "$foo"false, якщо fooвона визначена, але порожня, і відображається повідомлення про помилку під set -u. [ -n "${foo+1}" ]надійно перевіряє, чи fooвстановлено, але обробляти порожні та невстановлені змінні однаково зазвичай є хорошою ідеєю: [ -n "${foo:+1}" ]або просто, [ -n "$foo" ]якщо ви не переживаєте set -u.
Жил "ТАК - перестань бути злим"

Спасибі! У мене немає -quitдоступних, але трубопроводів head -n 1працює (як це робиться head -c 1, що зупиняється ще раніше, але, мабуть, з незначною користю). Також я допустив помилку, коли писав запитання без коду перед собою: я використовую wc -lв іншому випадку, де мені потрібно знати загальну кількість знайдених файлів. У випадку, коли я лише перевіряю, чи є відповідники, я використовував if [ -z `find … ` ].
Кріс Пейдж

6

Ви можете використовувати -quitдію, щоб зупинитись після першого матчу. Ви, ймовірно, захочете поєднати це з іншою дією (на кшталт -print), або не зможете сказати, чи знайшов щось таке.

Наприклад, find ... -print -quitбуде надруковано шлях першого відповідного файла, а потім вийде. Або ви можете використовувати-printf 1 -quit для друку 1, якщо є відповідність, і нічого, якщо його немає.

findСтатус виходу відображає, чи були помилки під час пошуку, а не те, чи знайшли щось, тож ви повинні перевірити його вихід, щоб побачити, чи є відповідність.


-quitє розширенням GNU. Він не працюватиме в системах, що використовують інші реалізації find (1), такі як OS X, BSD і, мабуть, більшість комерційних Unices.
Воррен Янг

Дякую, це корисно знати, якщо я використовую іншу систему. На жаль, ні -quit, ні -printf недоступні у моїй (Mac OS X).
Кріс Пейдж

4

Вихід 0 легко знайти, вихід> 0 складніше, оскільки це відбувається лише з помилкою. Однак ми можемо це зробити:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

Зауважте, що це рішення є більш ефективним, ніж використання підшару; виконувати помилку, безумовно, швидше, ніж виконувати навіть Dash:

$ cat alfa.sh bravo.sh charlie.sh delta.sh
find -name non-existing-file -exec false {} +
find -name existing-file -exec false {} +
[ "$(find -name non-existing-file)" ]
[ "$(find -name existing-file)" ]

$ strace dash alfa.sh | wc -l
807

$ strace dash bravo.sh | wc -l
1141

$ strace dash charlie.sh | wc -l
1184

$ strace dash delta.sh | wc -l
1194

0

Ви можете перетворити його в стан оболонки, наприклад:

[ "$(find . ...)" '!=' '' ] && echo Found || echo Not found

Де ...ваша умова відповідності, наприклад -name *.txt.

Деякі інші приклади:

[ "$(find /etc -name hosts)" ] && echo True || echo False
[ ! -z "$(find /etc -name hosts)" ] && echo True || echo False
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.