Copie apenas arquivos regulares de um diretório para outro

12

Eu gostaria de copiar um conteúdo do diretório 1 para o diretório 2. No entanto, gostaria de copiar apenas arquivos (e não diretórios) do meu diretório 1. Como posso fazer isso?

cp dir1/* dir2/*

então ainda tenho o problema de diretórios.

Além disso, todos os meus arquivos não têm nenhuma extensão . não vai fazer o truque

user1058398
fonte
1
Não sei o que as extensões têm a ver com isso.
ctrl-alt-Delor
1
cp dir1/* dir2oucp -t dir2 dir1/*
ctrl-alt-delor
@richard Há um hábito bastante comum no mundo do DOS de não usar extensões para diretórios, o que ainda sobrevive até certo ponto, levando algumas pessoas a supor que, se houver um ponto, ele não será um diretório e vice-versa.
Gilles 'SO- stop be evil' (
ok, mas ainda não relevante.
Ctrl-alt-delor

Respostas:

18
cp dir1/* dir2

cpnão copiará diretórios, a menos que seja explicitamente instruído a fazê-lo (com, --recursivepor exemplo, consulte man cp).

Nota 1: cp provavelmente sairá com um status diferente de zero, mas os arquivos serão copiados de qualquer maneira. Isso pode ser um problema quando o encadeamento de comandos com base em códigos de saída: &&, ||, if cp -r dir1/* dir2; then ..., etc. (graças a contrebis para o seu comentário sobre essa questão )

Nota 2 : cpespera que o último parâmetro seja um único nome ou diretório de arquivo. Realmente não deve haver curinga *após o nome do diretório de destino. dir2\*será expandido pelo shell exatamente como dir1\*. Coisas inesperadas vão acontecer:

  • Se dir2estiver vazio e dependendo do seu shell e configurações:
    • você pode receber apenas uma mensagem de erro, que é o melhor cenário.
    • dir2/*será levado literalmente (procurando um arquivo / diretório chamado *), o que provavelmente também levará a um erro, a menos *que exista realmente.
    • dir2/*será apenas removido completamente do comando, saindo cp dir1/*. Que, dependendo da expansão de dir1/*, pode até destruir dados:
      • Se dir1/*corresponder apenas a um arquivo ou diretório, você receberá um erro cp.
      • Se dir1/*corresponder exatamente a dois arquivos, um será substituído pelo outro ( Ruim ).
      • Se dir/*corresponder a vários arquivos e a última correspondência for a, você receberá uma mensagem de erro.
      • Se a última correspondência de dir/*for um diretório, todas as outras correspondências serão movidas para ele.
  • Se dir2não estiver vazio, depende novamente:
    • Se a última correspondência de dir2/*for um diretório, dir1/*e as outras correspondências de dir2/*serão movidas para.
    • Se a última correspondência de dir2/*for um arquivo, você provavelmente receberá uma mensagem de erro, a menos que dir1/* corresponda apenas a um arquivo.
Adaephon
fonte
$ cp dir1/* dir2-> cp: dir1/isadir is a directory (not copied).sai com o status 1 para mim.
11136 contrebis
1
Sim, também sai com o status 1 para mim. Mas, mesmo assim, cpcopia os arquivos correspondentes dir1/*em todos os sistemas que verifiquei: Arch Linux, Ubuntu 14.04, OpenBSD 3.9 e 5.5, SuSE Linux 8.1, FreeBSD 6.2, Solaris 8, 9 e 10 (onde cprealmente sai com o código 2). Portanto, esse comportamento não é novo (o SuSE 8.1 é de 2002) nem é limitado ao Linux. cpsai com um código de saída diferente de zero porque não pôde fazer tudo o que foi solicitado. Isso não significa que não faz nada .
Adaephon
3
Claro, achei interessante notar que, se você estiver encadeando comandos, &&isso pode causar um problema. Eu estava tentando algo assim, embora não me lembre do contexto agora.
contrebis
Isso não copia arquivos ocultos.
precisa saber é o seguinte
@felwithe A inclusão de *arquivos ocultos ou como incluir arquivos ocultos depende do shell. Se o *arquivo não incluir arquivos ocultos, você poderá combiná-los .*. Observe que isso incluirá .e ..ativará bashe dashnão ativará zsh. No contexto desta resposta, você pode se safar cp dir1/* dir1/.* dir2porque .e ..são diretórios e não serão copiados. zshTambém pode ser feito para incluir arquivos ocultos com *(D).
Adaephon
6

É o shell que expande curingas, não os comandos. Então, cp dir1/* dir2/*primeiro expanda os dois curingas, depois chame cpo resultado. Aparentemente, isso não é o que você espera: dependendo de quantos arquivos já existem dir2, você dir2/*pode expandir para um ou mais argumentos. O comando cpnão sabe quais argumentos vieram da expansão do primeiro padrão e quais vieram da expansão do segundo padrão. Ele espera que seu último argumento seja o nome do diretório de destino. Portanto, para copiar todos os arquivos do diretório dir1para o diretório dir2, o último argumento deve ser o diretório dir2:

cp dir1/* dir2

Como *corresponde a todos os arquivos, cptenta copiar todos os arquivos. Isso inclui diretórios: diretórios também são arquivos. Ignora diretórios, mas relata um erro. Ele copia o conteúdo de arquivos especiais, como pipes nomeados (é melhor que algo esteja gravando neles, ou cpbloqueará), etc.

Para copiar apenas arquivos regulares , você precisa restringir a correspondência. No zsh, você pode usar o qualificador glob . para isso:

cp dir1/*(.) dir2

Outras conchas não têm isso. Você pode usar o findcomando para filtrar os tipos de arquivo. Supondo que você esteja executando Linux ou Cygwin não incorporado:

find dir1 -maxdepth 1 -type f -exec cp -t dir2 {} +

No Linux, FreeBSD e OSX:

find dir1 -maxdepth 1 -type f | xargs -I {} cp {} dir2
Gilles 'SO- parar de ser mau'
fonte
Existe um motivo para especificar -maxdepth 1. Além disso, existe uma maneira de copiar e preservar recursivamente a hierarquia de diretórios original no diretório de destino?
Abdull
@ Abdull Sem -maxdepth 1, o findcomando recursaria em subdiretórios, o que não era desejado aqui. Se você deseja copiar toda a árvore de diretórios incluindo subdiretórios, é uma questão completamente diferente, ea resposta é muito mais simples: cp -a dir1 dir2.
Gilles 'SO- stop be evil'
0

Abaixo está o comando para copiar o arquivo do diretório de origem para o de destino.

  1. Vá para a pasta de origem e escreva o comando abaixo:

    $ cp fileName destination directory path

Exemplo:

cp publichOT.sh  /data/home/useradmin
Tapan Dubey
fonte