Qual é o argumento que falta para -exec?

15

Eu uso o comando a seguir 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 posso excluir após algumas semanas se ninguém pedir seus arquivos de volta. O diretório de destino possui subdiretórios por nome de usuário, assim como o diretório de archive.

Este é o comando que eu uso:

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

Sugeri uma versão modificada deste para responder a uma pergunta sobre perguntar ubuntu, outro usuário editou o código para alterar o fim da linha \;para +como ele é mais rápido (e mais correto?). Veja aqui

No entanto, o uso +dessa maneira funciona se o -execcomando estiver, ls -lhmas não no comando real que eu uso. Se eu tentar, +recebo uma mensagem de erro:

find: missing argument to '-exec'

Não entendo por que 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 cegamente.

Arronical
fonte
Você está se referindo a esta resposta ? Isso pode explicar o porquê
Wilf
Obrigado @Wilf Atualizei para mostrar em qual resposta a edição aconteceu. O link que você forneceu tem outro link que explica de uma maneira que meu cérebro pode lidar.
Arronical
Obrigado @souravc de uma maneira cíclica, essa pergunta é do usuário que editou meu comando! Finalmente, recebo +vários argumentos para o mesmo comando, mas mvnão consigo lidar com isso!
Arronical
Mv @Arronical pode, ver a minha resposta ^^
caos

Respostas:

19

O usuário nesse post pode dizer que o +sinal no final de um -execcomando é mais rápido, mas não o porquê.

Vamos assumir o find comando retorne os seguintes arquivos:

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

O -execcomando normal (-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 é construir, adicionando vários arquivos combinados 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 processar deve estar no final do comando, não no meio. É por isso que findlança missing argument to '-exec'no seu exemplo; falta o fechamento {}.

caos
fonte
Eu sempre me perguntei por que find -execexige {}que seja o último argumento, quando usado com +. Alguém sabe por que essa decisão de design foi tomada, em vez de deixar construções como a linha de comando do OP funcionar?
Peter Cordes
11

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

O terminador '+' exec é mais rápido que '\;'  consulte /ubuntu/558817/what-is-the-difference-between-using-and-in-exec-command;  e criar um arquivo de backup a partir do arquivo original é uma boa ideia

... 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 daqui :

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

ls file1
ls file2
ls file3

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

ls file1 file2 file3

Existem outras formas disponíveis usando ;e +também (de daqui :)

Portanto, o seguinte exemplo de sintaxe é permitido 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 de qualquer maneira, como é a sintaxe mv [OPTION]... SOURCE DEST, a menos que a -topção ou similar seja usada. No entanto, ele deve funcionar lssem opções extras, etc., pois elas podem entender quando vários nomes de arquivos são fornecidos. Também +pode ser necessário escapar (ie \+)

Wilf
fonte
As duas ótimas respostas, mas eu tenho que dar ao caos por ser um pouco mais rápido e explicar os mv -t+ 1s!
Arronical