Tive uma resposta embaraçosamente abrangente aqui antes, mas a resposta de Denis me lembrou que eu sentia falta da coisa mais básica. Então, eu apaguei minha resposta original. Mas como ninguém disse essa coisa muito básica, 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ço. Como posso copiá-los para um diretório de destino". No começo, 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 faz é separar a lista de argumentos em tokens e (aqui está o que ninguém disse de maneira definitiva) os espaços separados por tokens . (As novas linhas também separam os tokens, e é por isso que o teste de Doug Harris com uma lista separada de novas linhas teve o mesmo resultado.) Ou seja, o shell espera e já pode lidar com 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
O único problema é 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ê? Como o comando interno cat list.txt
é processado primeiro pelo shell e se expande file1 file2 file3...file#
, o que é exatamente o que o shell espera e deseja nessa parte do comando. Se não funcionou, então (1) você teve um erro de digitação ou (2) seus nomes de arquivos eram de alguma forma 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 cp
trabalhar, colocando essa lista onde ela pertence em todo o comando. Novamente, o próprio comando é este na estrutura:
cp list-of-files target_directory
É fácil ver como tudo isso se reúne nesta versão:
cp $(<list.txt) new_folder
$()
faz com que o shell execute o comando entre parênteses e substitua sua saída nesse ponto da linha maior. Em seguida, o shell executa a linha como um todo. A propósito, $()
é uma versão mais moderna do que você já estava fazendo com backticks (`). Próximo: <
é um operador de redirecionamento de arquivo. Diz ao shell para despejar o conteúdo da list.txt
entrada padrão. Como o $()
bit é processado primeiro, eis 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 cp
comando normal que você queria.
Percebo que estou batendo muito nesse cavalo (talvez muito morto), mas acho que vale a pena. Entender exatamente como o shell processa um comando pode ajudá-lo a escrevê-lo melhor e simplificar muito. Também mostrará onde é provável que os problemas estejam escondidos. Nesse caso, por exemplo, minha primeira pergunta para você deveria ter sido sobre nomes de arquivos engraçados ou um possível erro de digitação. Não foram necessárias acrobacias.