por que isso funciona em um shell para loop, mas não por si só

1

por que isso funciona

for X in A* ; do cp $X/output.txt output/$X.txt ; done

mas não isso

cp A*/output.txt output/A*.txt

Para copiar o arquivo output.txt de várias pastas chamadas A1, A2, A3, A4 etc. em uma pasta combinada chamada "output", fornecendo a cada arquivo de texto o nome da pasta de origem.

Kirt
fonte
Eu imaginaria porque cp não é iterativo por si só e porque como A * é um curinga à esquerda, mas não pode ser tratado como um à direita (não há enumeração paralela, e os curingas funcionam apenas para entrada, saída, onde são totalmente ambíguas), tornando-se um literal 'A *', não A1, A2, etc. alguma construção em loop é necessária para expandir as duas instâncias de A * para expandi-las e mantê-las sincronizadas a cada iteração . X é uma variável que é atualizada em cada loop. A * não é.
Frank Thomas

Respostas:

5

Como o shell expande a A*.txtpeça para vários caminhos antes de ser passada para o comando que está sendo chamado ( cpneste caso).

Isso significa que, no primeiro caso, se você tiver arquivos com o nome A1.txt, A2.txt, A3.txt e A4.txt e os diretórios A1, A2, A3 e A4, cada um contendo output.txt, ele se expandirá para algo como :

for X in A1.txt A2.txt A3.txt A4.txt ; do cp $X/output.txt output/$X.txt ; done

e no segundo caso, ele se expande para:

cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A*.txt

onde a output/A*.txtpeça pode ou não ser expandida, dependendo da existência de algo no outputdiretório que corresponda ao glob. Se isso acontecer, fica ainda pior, como:

cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A8.txt output/A9.txt

Como cpquando vários arquivos de origem desejam um diretório de destino no final, ele não sabe como lidar com isso e simplesmente levanta as mãos e gera um erro.

um CVn
fonte
0

O motivo é que, se houver mais de dois argumentos cp, o último deve ser um diretório. A página de manual do cp declara:

Sinopse

cp [OPTION] ... [-T] SOURCE DEST

cp [OPÇÃO] ... FONTE ... DIRETÓRIO

cp [OPÇÃO] ... -t FONTE DO DIRETÓRIO ...

Descrição

Copie SOURCE para DEST ou várias SOURCE (s) para DIRECTORY.

O comando que você escreveu,

  cp file1 file2 file3 file4

foi destinado a significar

 cp file1 file3; cp file2 file4

mas não, pelo motivo acima. O loop for produz exatamente as duas instruções imediatamente acima, que é o que você realmente deseja.

MariusMatutiae
fonte