Arquivo duplicado x vezes no shell de comando


22

Eu tento duplicar um arquivo de vídeo x vezes da linha de comando usando um loop for, tentei assim, mas não funciona:

for i in {1..100}; do cp test.ogg echo "test$1.ogg"; done

5
Seu único erro não é o echoque não deveria estar lá e o $1que deveria estar $i?
Julie Pelletier

se eu remover o eco e usar apenas test$1.ogg, ele diz: test.ogg e test.ogg são os mesmos arquivos , então parece que $ 1 não é reconhecido?
Preto

@ EdwardBlack: Parece que eu entendi mal suas necessidades. Essa solução não é adequada.
cuonglm

@JuliePelletier, droga, às vezes acontece comigo que eu escrevo acidentalmente em $1vez de $i, é cedo pela manhã, desculpe ... obrigado. Vou usar $xno futuro, em vez de$i
Preto

Respostas:


25

Seu código do shell tem dois problemas:

  1. O echonão deveria estar lá.
  2. A variável $iestá digitada incorretamente como $1no nome do arquivo de destino.

Para fazer uma cópia de um arquivo no mesmo diretório que o próprio arquivo, use

cp thefile thecopy

Se você inserir mais alguma coisa, por exemplo,

cp thefile theotherthing thecopy

assume-se que você deseja copiar thefilee theotherthingpara o diretório chamado thecopy.

No seu caso, ele procura especificamente um arquivo chamado test.ogge um nomeado echopara copiar para o diretório test$1.ogg.

O $1mais provável será expandir para uma sequência vazia. É por isso que, quando você exclui o echocomando, você obtém "test.ogg e test.ogg são os mesmos arquivos"; o comando que está sendo executado é essencialmente

cp test.ogg test.ogg

Provavelmente é um erro de digitação.

No final, você quer algo como isto:

for i in {1..100}; do cp test.ogg "test$i.ogg"; done

Ou, como alternativa

i=0
while (( i++ < 100 )); do
  cp test.ogg "test$i.ogg"
done

Ou, usando tee:

tee test{1..100}.ogg <test.ogg >/dev/null

Nota: Isso provavelmente funcionaria para 100 cópias, mas para milhares de cópias pode gerar um erro "lista de argumentos muito longa". Nesse caso, volte a usar um loop.


12

Curto e preciso

< test.ogg tee test{1..100}.ogg

ou melhor ainda

tee test{1..100}.ogg < test.ogg >/dev/null

consulte uso do comando tee para obter mais ajuda.

Atualizar

como sugerido por @Gilles, usar teetem o defeito de não preservar nenhum metadado de arquivo. Para superar esse problema, talvez seja necessário executar o comando abaixo:

cp --attributes-only --preserve Source Target

3
Isso é potencialmente mais rápido do que várias chamadas para cp(depende do tamanho do arquivo em relação à memória disponível), mas tem o defeito de não preservar nenhum metadado do arquivo.
Gilles 'SO- stop be evil' -

@ Gilles ohh, podemos superar isso?
Rahul

3
Você pode correr cp --attributes-onlydepois.
Gilles 'SO- stop be evil'

@Gilles obrigado, atualizei minha resposta conforme sua ajuda.
Rahul

FWIW nenhuma das outras respostas usadas cp -ppara preservar os metadados.
roaima 6/06

11
for i in {1..100}; do cp test.ogg "test_$i.ogg" ; done

1
Expansões variáveis ​​devem ser citadas.
cat

1

O comando a seguir copiará o arquivo.a 5 vezes:

$ seq 5 | xargs -I AA cp file.a fileAA.a

Se você preferir dd (não é o mesmo que cp!):

$ seq 5 | xargs -I AA dd if=file.a of=fileAA.a

0

Você não chamou a variável i ao copiar

use o script abaixo. Como testado, funcionou bem

for i in {1..10}; do cp -rvfp test.ogg test$i.ogg ;done

3
É o mesmo que as duas respostas anteriores e um comentário, exceto (1) a pergunta faz cerca de 100, e sua resposta usa 10, (2) você adicionou desnecessariamente as -rvfopções cpe (3) você não citou sua expansão variável . (Observe também que é convencional ter um espaço entre símbolos de pontuação como ;e a palavra a seguir.) A adição da -popção é valiosa, mas (4a) já foi abordada (nos comentários) e (4b) sua resposta não é útil se você não explicar o que está fazendo.
Scott
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.