Por que meu pipeline não funciona?

Por que meu pipeline não funciona?

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 mvcomando 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 -execaçã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.

informação relacionada