Как вы выводите имя файла в команде 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туда, но затолкал, как мне это сделать (желательно просто)?

Arronical
источник

Ответы:

36

просто добавьте -printfопцию перед

find -printf '%p' -exec command \;
Fiximan
источник
4
Прекрасно, я изменил '%p'на '%p\n'так, чтобы имя предшествовало выводу проверки в его собственной строке.
Arronical
17
@ Arronical, если это тот формат, который вы хотите, вы можете заменить (отформатированный) -printf '%p\n'на более простой-print
SteelDriver
4
find -name <a_name> -print -exec command {} \;
Толивейра
14

Если вы не хотите рекурсии, нет никакого смысла в использовании find. Гораздо проще сделать это непосредственно в оболочке:

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

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

Это можно запустить либо напрямую из командной строки, либо из скрипта без изменения формата.

terdon
источник
1
Это выглядит как лучший способ достижения моей цели, но я должен был дать ответ Фиксиману только потому, что мой заголовок и вопрос findтак много. Спасибо за улучшение моих знаний, хотя!
Arronical
Это требует использования шара. Глобализация, безусловно, полезна и эффективна, но по моему личному опыту, синтаксис сложнее настроить, и часто в конечном итоге нужны другие вещи, такие как dotglobи globstarв bash, что создает более длинный и более сложный скрипт. Я склонен экономить глобусы для больших сложных задач, в то время как findсинтаксис проще собрать на лету, просто собрав несколько фильтров и команд в одну строку.
user5359531
@ user5359531 здесь не нужны ни globstar, ни dotglob (если вы не знаете, что у вас есть скрытые файлы и действительно хотите их получить). Это, очевидно, вопрос мнения, но вы первый человек, с которым я когда-либо сталкивался, который считает довольно тупой формат findболее простым. Я всегда предпочитаю globs, findтак как я не только нахожу их намного проще, но и безопаснее, когда имеешь дело с произвольными именами файлов, которые передаются другим программам
тердон
6
find ./* -maxdepth 0 -type d -exec bash -c 'echo "{}"; svnadmin verify "{}"' \;

Я добавил, -type dесли это только каталоги.

7171u
источник
Я бы процитировал {}, по крайней мере, вsvnadmin verify {}
Кос
Спасибо за быстрый ответ. Таким образом, в этой команде -execпорождает дочернюю оболочку, в которой выполняются две команды, используя в ;качестве конца строки?
Arronical
5

Попробуй это:

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

Если вам нужны каталоги (спасибо заметке @kos):

for f in */ ; do echo  -n "${f}:"; svnadmin verify "${f}"; done
Maythux
источник
Хорошо, но при этом будут обрабатываться и файлы: for f in */будут обрабатываться только каталоги
kos
Будет ли это работать только в сценарии? Или я могу выдать его в командной строке?
Arronical
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 "{}"' \; 
AB
источник
-pruneвыглядит интересно. Раньше я ./* -maxdepth 0не возвращался .из команды поиска. Это не вызывает никаких критических ошибок, но я предпочитаю, чтобы их не было.
Arronical
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
Ves
источник
-1

Это напечатает имя и содержимое файлов только рекурсивно.

find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Прашант Адлинге
источник