Como você gera o nome do arquivo no comando find ao usar -exec?


33

Eu uso a seguinte linha para encontrar todos os subdiretórios do PWD e executar svnadmin verifyem cada diretório (eu já sei que eles são repositórios do Subversion)

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

Isso funciona bem, além do fato de que a saída se parece com isso:

* 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.

Eu realmente gostaria findde imprimir o nome do arquivo antes de executar o svnadmin verifycomando, para facilitar o registro.

Eu tentei me espremer um pouco ls, mas entendi, como devo fazer isso (de preferência simplesmente)?

Respostas:


36

basta adicionar uma -printfopção antes

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

4
Adorável, mudei '%p'para '%p\n'para que o nome preceda a saída de verificação em sua própria linha.
Arronical

17
@Arronical se esse for o formato que você quiser, você pode substituir o (formatada) -printf '%p\n'com o mais simples-print
steeldriver

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

14

Se você não quiser se recuperar, não há sentido em usá-lo find. É muito mais simples fazê-lo diretamente no shell:

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

O for d in */irá encontrar todos os diretórios ( */garante apenas diretórios e nenhum arquivo foi encontrado); o echo "$d"imprimirá o nome do diretório; o svnadmin verify "$d"irá verificar o diretório.

Isso pode ser executado diretamente da linha de comando ou de um script sem alteração no formato.


1
Parece uma maneira melhor de alcançar meu objetivo, mas tive que dar a resposta a Fiximan apenas porque meu título e pergunta se referem findmuito. Obrigado por melhorar meu conhecimento!
Arronical

Isso requer o uso de uma glob. O globbing é definitivamente útil e poderoso, mas, na minha experiência pessoal, a sintaxe é mais difícil de configurar e muitas vezes acaba precisando de outras coisas como dotglobe globstarno bash, o que cria um script mais longo e complicado. Costumo guardar globs para grandes tarefas complicadas, enquanto finda sintaxe é mais fácil de se juntar rapidamente, juntando vários filtros e comandos em uma única linha.
user5359531

@ user5359531 nem globstar nem dotglob (a menos que você saiba que possui arquivos ocultos e realmente os deseja) são necessários aqui. Obviamente, isso é uma questão de opinião, mas você é a primeira pessoa que eu já vi que considera o formato bastante obtuso de findmais simples. Eu sempre prefiro os globs, findpois não apenas os acho muito mais simples, mas também são mais seguros ao lidar com nomes de arquivos arbitrários que são passados ​​para outros programas.
terdon

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

Eu adicionei -type dse são apenas diretórios.


Gostaria de citar {}, pelo menos emsvnadmin verify {}
kos

Obrigado pela resposta rápida. Portanto, nesse comando o -execspawn é gerado por um shell filho, no qual os 2 comandos são executados, usando ;como fim de linha?
Arronical

5

Tente o seguinte:

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

Se você quiser apenas diretórios (Graças à @kos note):

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

Bom, mas isso também processará arquivos: for f in */processará apenas diretórios
kos

Isso funcionará apenas em um script? Ou posso emitir na linha de comando?
Arronical

1
@Arronical funcionará também como linha de comando
Maythux

2
  • Use em . -maxdepth 1vez de ./*, você precisa apenas do primeiro nível na estrutura de pastas
  • Use -type d, você precisa apenas de pastas
  • Use ! -name ".", você não precisa.
  • Use -execpara iniciar um shell
  • Use sh -cpara iniciar comandos dentro do shell

Seu comando

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

ou mais curto

  • Use -prunese o arquivo for um diretório, não desça nele

Seu comando

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

-pruneparece interessante. Eu costumava ./* -maxdepth 0evitar retornar .do comando find. Não causa nenhum erro crítico, mas prefiro não ter isso na minha saída.
Arronical

1

findpossui sinalizadores de opção para impressão, que já são mencionados em outras respostas. Se olharmos para o problema da perspectiva de executar vários comandos para o mesmo arquivo processado atualmente, findpermite o uso de várias -execinstruções. Isso significa que poderíamos optar por usar:

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

Mais uma vez, nota que esta abordagem é aplicável não apenas para imprimir com echo, printfou outras utilidades, mas também outros comandos.


0

Pode ser útil canalizar a findsaída para readloop:

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

Permite executar uma sequência de comandos composta mais complicada com nomes de arquivos retornados por find, como neste lsexemplo elegante :

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

-1

Isso imprimirá o nome e o conteúdo dos arquivos somente recursivamente.

find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.