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. para uma pasta combinada chamada "saída", dando a cada arquivo de texto o nome da pasta de onde veio.
Responder1
Como o shell expande a A*.txt
peça paramúltiplocaminhos antes de ser passado para o comando que está sendo invocado ( cp
neste caso).
Isso significa que no primeiro caso, se você tiver arquivos chamados A1.txt, A2.txt, A3.txt e A4.txt e diretórios A1, A2, A3 e A4, cada um contendo output.txt, ele se expandirá paraalgo 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, expande-se para:
cp A1/output.txt A2/output.txt A3/output.txt A4/output.txt output/A*.txt
onde a output/A*.txt
parte pode ou não se expandir dependendo se existe algo no output
diretó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
Desde cp
quando recebe vários arquivos de origem quer um destinodiretóriono final, ele não sabe como lidar com isso e simplesmente levanta as mãos e dá um erro.
Responder2
A razão é que, se houver mais de dois argumentos para cp
, o últimodeveseja um diretório. OPágina de manual do cpafirma:
Sinopse
cp [OPÇÃO]... [-T] DESTINO FONTE
cp [OPÇÃO]... FONTE... DIRETÓRIO
cp [OPÇÃO]... -t FONTE DE 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
pretendia significar
cp file1 file3; cp file2 file4
mas isso não acontece, pelo motivo acima. O loop for produz exatamente as duas instruções imediatamente acima, que é o que você realmente deseja.