Як виводити ім'я файлу в команді find під час використання -exec?


33

Я використовую наступний рядок, щоб знайти всі підкаталоги PWD і запускатись svnadmin verifyу кожній директорії (я вже знаю, що вони є сховищами Subversion)

find ./* -maxdepth 0 -exec svnadmin verify {} \;

Це добре працює, окрім того, що результат виглядає так:

* Verifying repository metadata ...
* Verifying metadata at revision 1 ...
* Verifying metadata at revision 2 ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 9 ...
* Verifying metadata at revision 10 ...
* Verifying metadata at revision 12 ...
* Verifying metadata at revision 14 ...
* Verifying metadata at revision 15 ...
* Verifying metadata at revision 18 ...
* Verifying metadata at revision 20 ...
* Verifying metadata at revision 22 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.
* Verified revision 10.
* Verified revision 11.
* Verified revision 12.
* Verified revision 13.
* Verified revision 14.
* Verified revision 15.
* Verified revision 16.
* Verified revision 17.
* Verified revision 18.
* Verified revision 19.
* Verified revision 20.
* Verified revision 21.
* Verified revision 22.
* Verified revision 23.
* Verified revision 0.
* Verifying repository metadata ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 7 ...
* Verifying metadata at revision 9 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.

Я дуже хотів findби надрукувати ім'я файлу перед виконанням svnadmin verifyкоманди, щоб полегшити ведення журналу.

Я намагався трохи стиснути lsтам, але підбив це, як це робити (бажано просто)?

Відповіді:


36

просто додайте -printfпараметр раніше

find -printf '%p' -exec command \;

4
Прекрасний, я змінив '%p'до '%p\n'так , що ім'я передує перевірити висновок на його власної лінії.
Арронічний

17
@Arronical, якщо це потрібний вам формат, ви можете замінити (відформатований) -printf '%p\n'на простіший-print
steeldriver

4
find -name <a_name> -print -exec command {} \;
toliveira

14

Якщо ви не хочете повторювати, використовувати це не має сенсу find. Набагато простіше це зробити безпосередньо в оболонці:

for d in */; do echo "$d"; svnadmin verify "$d"; done

The for d in */знайде всі каталоги ( */забезпечує лише каталоги та файли не знайдені); echo "$d"друкуватиме ім'я каталогу файлів; svnadmin verify "$d"перевірить каталог.

Це можна виконати як безпосередньо з командного рядка, так і зсередини сценарію без зміни формату.


1
Це виглядає як кращий спосіб досягти своєї мети, але мені довелося дати відповідь Фіксіману лише тому, що findтак багато моїх назв та посилань на питання . Дякуємо, що вдосконалили мої знання!
Арронічний

Для цього потрібно використовувати глобус. Глобінг, безумовно, корисний і потужний, але в моєму особистому досвіді синтаксис складніше налаштувати, і часто виникає потреба в інших речах, таких як dotglobі globstarв башті, що створює довший і складніший сценарій. Я схильний економити глобуси для великих складних завдань, тоді як findсинтаксис легше з'єднати на льоту, просто з'єднавши купу фільтрів і команд в однолінійку.
користувач5359531

@ user5359531 тут не потрібні ні globstar, ні dotglob (якщо ви не знаєте, що у вас є приховані файли і дійсно хочете їх). Це, очевидно, питання думки, але ви перша людина, яку я коли-небудь зустрічав, яка вважає досить тупий формат findбільш простим. Я завжди віддаю перевагу глобусам, findоскільки не тільки вважаю їх набагато простішими, але вони також безпечніші при роботі з довільними іменами, які передаються іншим програмам.
terdon

6
find ./* -maxdepth 0 -type d -exec bash -c 'echo "{}"; svnadmin verify "{}"' \;

Я додав, -type dякщо це лише каталоги.


Я б процитував {}, принаймні,svnadmin verify {}
kos

Дякую за швидку відповідь. Отже, у цій команді -execнерестований дочірній оболонку, в якій виконуються 2 команди, використовуючи ;як кінець рядка?
Арронічний

5

Спробуйте це:

for f in * ; do echo  -n "${f}:"; svnadmin verify "${f}"; done

Якщо ви просто хочете каталогів (завдяки примітці @kos):

for f in */ ; do echo  -n "${f}:"; svnadmin verify "${f}"; done

Добре, але це також обробляє файли: for f in */оброблятиме лише каталоги
kos

Це буде працювати лише в сценарії? Або я можу видати його в командному рядку?
Арронічний

1
@Arronical працюватиме також як командний рядок
Maythux

2
  • Використовувати . -maxdepth 1замість цього ./*вам потрібно лише перший рівень у структурі папок
  • Використовуйте -type d, вам потрібні лише папки
  • Використовуйте ! -name ".", вам не потрібно.
  • Використовуйте -execдля запуску оболонки
  • Використовуйте sh -cдля запуску команд всередині оболонки

Ваша команда

find . -maxdepth 1 -type d ! -name "." -exec sh -c 'echo "{}"; svnadmin verify "{}"' \;

або коротше

  • Використовуйте, -pruneякщо файл - каталог, не спускайтеся в нього

Ваша команда

find . -mindepth 1 -prune -exec sh -c 'echo "{}"; svnadmin verify "{}"' \; 

-pruneвиглядає цікаво. Я раніше ./* -maxdepth 0уникав повернення .з команди find. Це не викликає критичної помилки, але я вважаю за краще не мати цього у своєму висновку.
Арронічний

1

findмає опціонні прапори для друку, які вже згадуються в інших відповідях. Якщо ми розглянемо проблему форми перспективи виконання декількох команд для одного і того ж файлу, який зараз обробляється, findдозволяє використовувати кілька -execоператорів. Це означає, що ми можемо вибрати:

find ./* -maxdepth 0 -exec echo {} \; -exec svnadmin verify {} \; 

Знову ж , зверніть увагу , що цей підхід можна застосувати не тільки друк з echo, printfабо іншими утилітами, а й інші команди.


0

Можливо, буде корисно передати findвисновок у readцикл:

find . | while read d; do echo "=== ${d}: ==="; svnadmin verify ${d}; done

Це дозволяє виконувати більш складні, складені послідовності команд з поверненими іменами файлів find, як у цьому фантазійному lsприкладі:

find . | while read f; do echo ${f} | figlet -k; done

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.