
Estou tentando criar um script bash que encontre todos os mp3s na minha pasta Downloads e os mova para uma pasta de músicas. Por que essa linha não funciona?
find ./ -type f -name \*.mp3 | mv *.mp3 /home/mitch/Desktop/Music/$ARTIST
Tentei usar um pipeline para que as informações do primeiro comando fossem traduzidas para o segundo, mas nunca usei um pipeline antes e não sei se estou fazendo errado ou se tenho uma ideia errada do que eles são usados para.
Responder1
O mv
comando não usa seu stdin, então você tem que traduzir o stdin para um parâmetro, e para isso pode ser usado xargs
:
find ./ -type f -name '*.mp3' | xargs mv -t /home/mitch/Desktop/Music/$ARTIST
Além disso, você pode usar diretamente a -exec
ação de find
:
find ./ -type f -name '*.mp3' -exec mv {} /home/mitch/Desktop/Music/$ARTIST ';'
Editar
Conforme apontado por @geirha, o primeiro comando não funciona se você tiver nomes de arquivos contendo espaços. Nesse caso, deveria ser o seguinte
find ./ -type f -name '*.mp3' -print0 | xargs -0 mv -t /home/mitch/Desktop/Music/$ARTIST
Responder2
A vantagem do xargs é a expansão da linha de comando. Se você tivesse um comando que retornasse uma quantidade muito grande de texto (ou muitos arquivos, todos em um comando), você precisaria de xargs.
Se você tiver vários milhares de arquivos em um diretório e quiser executar algum script dessa lista, você pode tentar " ./myprogram *
", mas se o seu programa tiver algum limite no tamanho de um parâmetro, você pode estourar o buffer expandindo *. Além disso, a própria linha de comando tem limites, portanto o comando pode falhar porque o buffer da linha de comando está sobrecarregado. O uso de xargs evitará o problema.
por último, -print0 em find colocará delimitadores nulos para espaços nos nomes de arquivos retornados, e a opção -0 em xargs interpretará esses nulos. Ler man xargs
.