Preciso percorrer pastas e contar arquivos em TARs com o mesmo nome.
Eu tentei isso:
find -name example.tar -exec tar -tf {} + | wc -l
Mas falha:
tar: ./rajce/rajce/example.tar: Not found in archive
tar: Exiting with failure status due to previous errors
0
Funciona quando há apenas um exemplo.tar.
Preciso de um número separado para cada arquivo.
Obrigado!
Responder1
Você precisa, tar -tf {} \;
em vez de tar -tf {} +
executar tar
cada tarball individualmente. No GNU man find
diz:
-exec command {} +
This variant of the -exec action runs the specified
command on the selected files, but the command line is
built by appending each selected file name at the end;
the total number of invocations of the command will be
much less than the number of matched files. The command
line is built in much the same way that xargs builds its
command lines. Only one instance of `{}' is allowed
within the com- mand. The command is executed in the
starting directory.
Seu comando é equivalente a tar tf example.tar example.tar
. Também está faltando [path...]
argumento - algumas implementações de
find
, por exemplo, BSD find retornarão find: illegal option -- n
erro. Em suma, deveria ser:
find . -name example.tar -exec tar -tf {} \; | wc -l
E observe que nesse caso wc -l
irá contar o número de arquivos em todos
example.tar
os arquivos encontrados. Você pode usar -maxdepth 1
para procurar
example.tar
arquivos apenas no diretório atual. Se você quiser pesquisar todos example.tar
recursivamente e imprimir os resultados de cada um individualmente (observe que $
aqui está umprompt de linha de comando
usado para indicar o início de uma nova linha, não faz parte do comando):
$ find . -name example.tar -exec sh -c 'tar -tf "$1" | wc -l' sh {} \;
3
3
e com nomes de diretório anexados:
$ find . -name example.tar -exec sh -c 'printf "%s: " "$1" && tar -tf "$1" | wc -l' sh {} \;
./example.tar: 3
./other/example.tar: 3
Responder2
Acho que o seu problema está na utilização do +
operador para o -exec
funcionamento do find
. O +
operador significa "Concatenar os resultados de find
uma lista separada por espaços e executar o comando especificado com essa lista como argumento".
Isso significa que se houver mais de um arquivo example.tar
(digamos, dois) em caminhos diferentes, seu -exec
comando será parecido com
tar -tf /path/1/to/example.tar /path/2/to/example.tar
etc. Isso, porém, será interpretado como "veja se existe um arquivo/caminho/2/para/exemplo.tarno arquivo TAR/caminho/1/para/exemplo.tar", o que obviamente não deveria ser o caso.
Você deve ficar bem se modificar seu código como
find -name example.tar -exec tar -tf {} \; | wc -l
que executará o tar
comando separadamente para cada arquivo encontrado.