Eu tive uma resposta embaraçosa aqui antes, mas a resposta de Denis essa coisa básica, eu acho que vale a pena colocar aqui.
A pergunta original é "Eu tenho um arquivo de texto com uma lista de nomes de arquivos separados por espaços. Como posso copiá-los para um diretório de destino". A princípio, isso pode parecer complicado ou complicado, porque você acha que precisa extrair os itens do arquivo de uma maneira específica. No entanto, quando o shell processa uma linha de comando, a primeira coisa que ele faz é separar a lista de argumentos em tokens e (aqui está o bit que ninguém disse abertamente) espaços tokens separados . (As linhas novas também separam tokens, e é por isso que o teste de Doug Harris com uma lista separada por nova linha teve o mesmo resultado.) Ou seja, o shell espera e já pode manipular uma lista separada por espaço.
Portanto, tudo o que você precisa fazer aqui é colocar a lista separada por espaço (que você já possui) no lugar certo em seu comando. Seu comando é uma variação disso:
cp file1 file2 file3...file# target
A única ruga é que você deseja obter a lista de arquivos de 1 a # do seu arquivo de texto.
Como Dennis aponta em seu comentário, sua tentativa original ( cp
cat list.txt new_folder
) já deveria ter funcionado. Por quê? Porque o comando interno cat list.txt
é processado primeiro pelo shell e expande para file1 file2 file3...file#
, que é exatamente o que o shell espera e deseja nessa parte do comando. Se não funcionasse, então (1) você tinha um erro de digitação ou (2) seus nomes de arquivos eram estranhos (eles tinham espaços ou outros caracteres incomuns).
A razão pela qual todas as respostas de Dennis funcionam é simplesmente que elas fornecem a lista necessária de arquivos para que cp
trabalhe, colocando essa lista onde ela pertence em todo o comando. Novamente, o comando em si é este em estrutura:
cp list-of-files target_directory
É fácil ver como tudo isso vem junto nesta versão:
cp $(<list.txt) new_folder
$()
faz com que o shell execute o comando dentro dos parênteses e, em seguida, substitua sua saída naquele ponto na linha maior . Então o shell executa a linha como um todo. A propósito, $()
é uma versão mais moderna do que você já fazia com backticks ('). Próximo: <
é um operador de redirecionamento de arquivos. Ele diz ao shell para descarregar o conteúdo de list.txt
para a entrada padrão. Como o $()
bit é processado primeiro, veja o que acontece em etapas:
-
cp $(<list.txt) new_folder
# split line into three tokens: cp, $(<list.txt), new_folder
-
cp file1 file2 file3...file# new_folder
# substitute result of $(<list.txt) into the larger command
Obviamente, o passo 2 é simplesmente o comando normal cp
que você queria.
Eu percebo que estou batendo muito (talvez muito morto) cavalo, mas acho que vale a pena fazer. Entender exatamente como o shell processa um comando pode ajudá-lo a escrever melhor e simplificar muito. Ele também mostrará onde os problemas provavelmente estarão ocultos. Neste caso, por exemplo, minha primeira pergunta a você deveria ter sido sobre nomes de arquivos engraçados ou um possível erro de digitação. Nenhuma acrobacia era necessária.