Melhor maneira de executar um comando em cada arquivo em uma árvore de diretórios

12

Parece haver várias maneiras de fazer isso, incluindo loops no shell script, find e xargs. Qual destes é o melhor e qual é o mais portátil?

    
por Brian Lyttle 10.08.2010 / 22:16

6 respostas

13
find . -exec <command> {} \;

para o diretório atual como raiz da árvore ou em geral:

find <directory> -exec <command> {} \;
    
por 10.08.2010 / 22:20
5

Use a opção -print0 para localizar e a opção -0 para xargs se você tiver nomes de arquivos ou diretórios com espaços:

find {dir} -print0 | xargs -0r {command}

A opção -print0 para localizar imprime os nomes de arquivos como uma lista separada por NUL e não separada por espaços em branco, enquanto a opção -0 para xargs instrui a quebrar sua entrada em NUL em vez de espaço em branco . Como NUL é um dos caracteres que não são permitidos em nomes de arquivos Unix, não há como ser confundido com parte de um nome de arquivo.

A opção -r está lá, então xargs não causará erro se não tiver entrada.

    
por 18.08.2010 / 03:55
3
Se a portabilidade é um problema, eu ficaria longe de maneiras específicas de fazer isso (existem muitas pessoas usando muitos shells diferentes, mas, em geral, encontrar e xargs são ferramentas realmente básicas que ninguém ousaria mudar em um maneira radical).

Usar argumentos básicos de find e xargs deve fornecer uma solução mais portátil.

    
por 10.08.2010 / 22:20
2

Se agrupar argumentos juntos é aceitável, encontre | O xargs provavelmente dará um melhor desempenho, já que executará o comando muito menos vezes que o find -exec. Se você quiser executar o comando a cada vez para cada arquivo ou executar no subdiretório do arquivo, você provavelmente deve usar find -exec ou -execdir.

Como regra, é preferível ficar longe dos loops específicos do shell; encontrar & xargs são suficientes para a maioria dos cenários.

    
por 10.08.2010 / 22:59
1

Certifique-se de que a versão do comando que você está usando não tenha um sinalizador para operação recursiva. :)

    
por 18.08.2010 / 08:07
0
find [args] -print | xargs {command}

Funciona melhor para mim.

    
por 10.08.2010 / 23:12