Como executo vários comandos ao usar find?

Como executo vários comandos ao usar find?

Estou tentando executar vários comandos em coisas que encontrei. Como posso conseguir isso?

find . -exec cmd1; cmd2

parece não funcionar; em vez disso, ele executa o cmd2 após o cmd1 ter sido executado em todos os arquivos.

Responder1

Nesta demonstração, usarei sh -c 'echo first; false'(ou true) para o primeiro -exec. Isso fornecerá alguma saída e também terá o efeito do código de saída selecionado. Então echo secondserá usado para o segundo. Suponha que haja um arquivo no diretório atual.

$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second

Um comando real deste tipo seria assim:

find . -type f \( -exec command1 \; -false -o -exec command2 \; \)

No segundo conjunto, os parênteses escapados agrupam as duas -execcláusulas. O -falseentre eles força o estado de teste para "falso" e -ofaz com que a próxima expressão (a segunda -exec) seja avaliada por causa do -false.

De man find:

expr1 expr2
Duas expressões seguidas são consideradas unidas por um "e" implícito; expr2 não é avaliado se expr1 for falso.

expr1 -a expr2
O mesmo que expr1 expr2.

expr1 -o expr2
Ou; expr2 não é avaliado se expr1 for verdadeiro.

Responder2

Se você não se importa com o fato de o cmd1 ser capaz de impedir a execução do cmd2 devido ao código de erro 0:

find . -exec cmd1 \; -exec cmd2 \;

A única maneira confiável de fazer com que ambos os comandos sempre executem isso é invocar findum shell que posteriormente executará os comandos em sequência:

find . -exec bash -c 'cmd1; cmd2' filedumper {} \;

Responder3

Se você não se importa em criar um script que execute cmd1 e cmd2, é apenas isto:

find . -exec myscript {} \;

ou

find . -exec myscript {} +

Usar \; ou + dependendo se o myscript pode lidar com mais de um arquivo por vez (fica complicado se houver espaços nos nomes dos arquivos, etc.).

Colocar o que você estava fazendo em um roteiro, na minha experiência, quase sempre valeu a pena. Se você tiver que fazer isso uma vez, terá que fazer novamente.

Mas um truque legal é colocar o achadodentroo roteiro:

if [ $# -gt 0 ]; then
    for each; do
        touch $each
    done
else
    find . -exec $0 {} +
fi

Então myscript funciona em quaisquer arquivos que você fornecer como argumentos para funcionar, mas se você não fornecer nenhum argumento, ele executará find no diretório atual e, em seguida, chamará a si mesmo nos arquivos encontrados. Isso contorna o fato de que find -exec não pode chamar funções shell que você definiu em seu script.

Responder4

tente o comando:

sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l

informação relacionada