Linha de comando: tubulação encontrar resultados para rm

140

Estou tentando elaborar um comando que exclui arquivos sql com mais de 15 dias.

A parte find está funcionando, mas não a rm.

rm -f | find -L /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups -type f  \( -name '*.sql' \) -mtime +15

Ele exibe uma lista exata dos arquivos que eu quero excluir, mas não os está excluindo. Os caminhos estão corretos.

usage: rm [-f | -i] [-dIPRrvW] file ...
       unlink file
/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/20120601.backup.sql
...
/usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/20120610.backup.sql

O que estou fazendo de errado?

jerrygarciuh
fonte

Respostas:

274

Você está realmente conduzindo rma saída da tubulação para a entrada de find. O que você deseja é usar a saída findcomo argumentos para rm:

find -type f -name '*.sql' -mtime +15 | xargs rm

xargsé o comando que "converte" sua entrada padrão em argumentos de outro programa ou, como eles colocam com mais precisão na manpágina,

construir e executar linhas de comando a partir da entrada padrão

Observe que se os nomes dos arquivos puderem conter caracteres em branco, você deve corrigir isso:

find -type f -name '*.sql' -mtime +15 -print0 | xargs -0 rm

Mas, na verdade, findtem um atalho para isso: a -deleteopção:

find -type f -name '*.sql' -mtime +15 -delete

Esteja ciente dos seguintes avisos em man find:

  Warnings:  Don't  forget that the find command line is evaluated
  as an expression, so putting -delete first will make find try to
  delete everything below the starting points you specified.  When
  testing a find command line that you later intend  to  use  with
  -delete,  you should explicitly specify -depth in order to avoid
  later surprises.  Because -delete  implies  -depth,  you  cannot
  usefully use -prune and -delete together.

PS Observe que canalizar diretamente para rmnão é uma opção, porque rmnão espera nomes de arquivos na entrada padrão. O que você está fazendo atualmente é direcioná-los para trás.

Lev Levitsky
fonte
1
Obrigado. Eu li a página de manual e tentei essa bandeira. Estou passando por um caminho completo, mas voltando "/ usr / www2 / bar / htdocs / foo / rsync / httpdocs / db_backups /: caminho relativo potencialmente não seguro". Alguma idéia do porquê?
jerrygarciuh
1
@jerrygarciuh dê uma olhada aqui .
Lev Levitsky
obrigado. Não tenho certeza se segui bem o post, mas quando emulei a solução e coloquei -delete no final do comando, ele excluiu todos os arquivos sql, independentemente do tempo de modificação ... mas não havia o aviso, então eu acho desse progresso ...
jerrygarciuh
1
@jerrygarciuh Ouch, espero que nada valioso tenha sido perdido ... mandiz: When testing a find command line that you later intend to use with -delete, you should explicitly specify -depth in order to avoid later surprises.Não sei bem o que isso importa, considerando as outras opções que você usou, mas você tentou isso?
Lev Levitsky
Não, eu não fiz, mas nada foi perdido. Esses arquivos são rsync-ed a partir de outro servidor onde também são armazenados.
Jerrygarciuh
26
find /usr/www/bar/htdocs -mtime +15 -exec rm {} \;

Selecionará arquivos em /usr/www/bar/htdocs mais de 15 dias e os removerá.

Suresh
fonte
Prefiro sua resposta do que a aceita por causa do "espaço no nome". É melhor manipulado com o comando "-exec" do que pipe. Obrigado.
Slim Aloui
3

Outro método mais simples é usar o locatecomando. Em seguida, canalize o resultado para xargs.

Por exemplo,

locate file | xargs rm
Gautam Sreekumar
fonte
2

Supondo que você não esteja no diretório que contém os arquivos de backup * .sql:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec rm -v {} \;

A opção -v acima é útil, pois fornecerá, verbalmente, quais arquivos serão excluídos à medida que são removidos.

Eu gosto de listar os arquivos que serão excluídos primeiro para ter certeza. Por exemplo:

find /usr/www2/bar/htdocs/foo/rsync/httpdocs/db_backups/*.sql -mtime +15 -exec ls -lrth {} \;
Nick Little
fonte