Usar o find antes de wc elimina o total

2

Estou usando find para pesquisar em todos os subdiretórios e no diretório atual para localizar todos os arquivos .py e, em seguida, executar wc -l para localizar o número de linhas. No entanto, quando eu uso find com wc, o campo Total é deixado de lado, diferente de quando eu corro wc sozinho. Alguém sabe por que isso está acontecendo?

find . -name \*.py -exec wc -l {} \;
  187 ./check.py
   43 ./file.py
   33 ./mitch.py
       ...
 1014 ./serve.py
   41 ./test_scripts/line_graph.py
   39 ./welcome.py

Mas não total, mas quando executo wc -l *.py em um diretório, obtenho um total:

wc -l *.py
 187 check.py
  43 file.py
  94 log_com.py
 154 log_results.py
  33 mitch.py
1014 serve.py
  39 welcome.py
1564 total
    
por taronish4 28.08.2013 / 19:33

2 respostas

1

wc gera apenas um valor Total quando é chamado com mais de um arquivo como argumentos.

Do manual do GNU :

If more than one file is given, wc prints a final line containing the cumulative counts, with the file name total.

No seu caso, você não pode obter uma saída Total , já que invoca wc uma vez para cada arquivo encontrado, portanto, cada chamada wc subseqüente não sabe sobre a anterior.

Se você ainda quiser a contagem total, poderá usar a opção globstar no Bash para recorrer aos diretórios e listar .py files:

shopt -s globstar
wc -l **/*.py

Ou, como sugere o grawity, com a opção find do -exec command {} + do GNU, ter find substituir todos os caminhos encontrados em {} , em vez de chamar cada um individualmente (embora haja um limite para o número de arquivos que pode substituir, assim como com a abordagem glob).

    
por 28.08.2013 / 19:38
1

Não há campo total porque existe apenas um arquivo.

Com a ação -exec command {} ; , find executa o comando uma vez para cada arquivo , com apenas um único argumento adicionado a cada vez. Portanto, não há nada em que cada invocação wc possa calcular o total de.

Você teria que usar -exec command {} + se você tivesse o GNU find ; caso contrário, você precisará enviar a lista de arquivos para xargs command .

(Nesta resposta eu não vou me incomodar com a sugestão usual de -print0 , porque se você não tiver o GNU encontrado, você não terá -print0 ou mesmo GNU xargs também. A versão do xargs suporta -d '\n' , use isso, porque a entrada padrão xargs parses não é muito segura.

Observe que isso ainda pode resultar em várias invocações de wc , porque a maioria dos sistemas operacionais (exceto talvez Hurd) tem um limite no comprimento máximo da linha de comandos e / ou número máximo de argumentos para um único comando, que um grande número de arquivos pode exceder. A sugestão de @hckck de usar **/*.py também teria o mesmo limite (os primeiros Unixes que tinham limites muito baixos eram o motivo pelo qual xargs foi criado em primeiro lugar).

Outra alternativa é usar awk para o cálculo final:

find ... | awk '$2 != "total" {sum += $1; print}
                END {printf "%7d total\n", sum}'
    
por 28.08.2013 / 19:40

Tags