Qual é o argumento que falta para -exec?

15

Eu uso o seguinte comando para limpar um diretório, de arquivos e diretórios com mais de 30 dias, e movê-los para um diretório de arquivamento que eu possa excluir depois de algumas semanas, se ninguém pedir seus arquivos de volta. O diretório de destino tem subdiretórios por nome de usuário, assim como o diretório de arquivamento.

Este é o comando que eu uso:

find /path/to/directory/username/ -mtime +30 -exec mv "{}" /path/to/archive/username/ \;

Eu sugeri uma versão modificada disso para responder uma pergunta sobre o ubuntu, outro usuário editou o código para alterar o final da linha \; para + , pois é mais rápido (e mais correto?). Veja aqui

No entanto, usar + dessa maneira funciona se o comando -exec for ls -lh , mas não no comando real que eu uso. Se eu tentar com + , recebo uma mensagem de erro:

find: missing argument to '-exec'

Eu não entendo porque está se comportando dessa maneira ou qual seria o comando correto. Por favor, não basta postar uma correção de comando, eu gostaria de entender, em vez de apenas seguir uma sugestão cega.

    
por Arronical 08.07.2015 / 15:38

2 respostas

19

O usuário nessa postagem pode dizer que o sinal + no final de um comando -exec é mais rápido, mas não o motivo.

Vamos supor que o comando find retorne os seguintes arquivos:

/path/to/file1
/path/to/file2
/path/to/file3

O comando normal -exec ( -exec command {} \; ) é executado uma vez para cada arquivo correspondente. Por exemplo:

find ... -exec mv {} /target/ \;

Executa:

mv /path/to/file1 /target/
mv /path/to/file2 /target/
mv /path/to/file3 /target/

Se você usar o sinal + ( -exec command {} + ), o comando será criado adicionando vários arquivos correspondentes no final do comando. Por exemplo:

find ... -exec mv -t /target/ {} +

Executa:

mv -t /target/ /path/to/file1 /path/to/file2 /path/to/file3

Para usar o sinalizador + corretamente, o argumento a ser processado deve estar no final do comando, não no meio. É por isso que find trows missing argument to '-exec' no seu exemplo; falta o fechamento {} .

    
por chaos 08.07.2015 / 16:00
10

O usuário explicou sua edição ....

... usando este link . Eu acho que, basicamente, em vez de usar vários comandos, ele envia todos os nomes de arquivos para uma instância de comando, para acelerar as coisas. Aqui está um exemplo de aqui :

  

Usando -exec com um ponto-e-vírgula ( find . -exec ls '{}' \; ), será executado

ls file1
ls file2
ls file3
     

Mas se você usar um sinal de mais ( find . -exec ls '{}' \+ ), todos   nomes de arquivos serão passados como argumentos para um único comando:

ls file1 file2 file3

Há outros formulários disponíveis usando ; e + também (de aqui :)

Portanto, a seguinte sintaxe de exemplo é permitida para o comando find:

find . -exec echo {} \;
find . -exec echo {} ';'
find . -exec echo {} ";"
find . -exec echo {} \+
find . -exec echo {} +
No entanto, não tenho certeza se isso funcionará com o comando move, pois a sintaxe é mv [OPTION]... SOURCE DEST , a menos que a opção -t ou similar seja usada. No entanto, ele deve funcionar com ls sem opções extras, etc., pois eles podem entender quando vários nomes de arquivos são fornecidos. O + também pode precisar ser escapado (por exemplo, \+ )

    
por Wilf 08.07.2015 / 16:00