Copiando recursivamente arquivos ocultos - Linux

19

Existe uma maneira fácil de copiar recursivamente todos os arquivos ocultos em um diretório para outro diretório? Gostaria de fazer backup apenas de todos os arquivos de configurações em um diretório pessoal, não dos arquivos normais. Eu tentei:

cp -R .* directory

mas também reconhece .e ..copia recursivamente todos os arquivos não ocultos. Existe uma maneira de obter cp para ignorar .e ..?

Zifre
fonte
Existe alguma diferença entre -re -R?
Chaminda Bandara

Respostas:

15

Meu favorito para mover dirs em geral tem sido:

tar cvf - . | (cd /dest/dir; tar xvf -)

que coloca o diretório atual em stdout e o canaliza para um subshell que primeiro o CD está no diretório de destino antes de desdobrar stdin. Simples, direto, extensível - considere o que acontece quando você substitui o () por um ssh para outra máquina. Ou, para responder sua pergunta, você pode fazer:

tar cvf - .* --exclude=\. --exclude=\.\. | (cd /dest/dir; tar xvf -)
pjz
fonte
11
Obrigado, a opção de exclusão é o que eu precisava. Eu já fiz isso de outra maneira, mas vou manter isso para referência futura. Isso parece realmente flexível (embora talvez mais lento).
Zifre 5/05/09
11
Bom conselho. Eu tenho algumas melhorias: 1) Use cd /dest/dir && tar xvf -. O &&impedirá de exibir o diretório de origem se você tiver um erro de digitação no destino. 2) Você só precisa do vsinalizador tar em um dos comandos tar (ou nenhum).
Tom Shaw
Justo. Eu também fui conhecido para agrupar as coisas de outra maneira: para copiar um srcdir remoto para aqui, não(cd /src/dir && tar cf - .) | tar xvf -
pjz
17

Quase sempre que isso pode ser resolvido apenas com:

cp -R .[a-zA-Z0-9]* directory

É muito incomum ter um arquivo oculto que não comece com um desses caracteres.

Outras correspondências de padrões estão disponíveis ( .??*, .[^.]*) - veja os comentários

Alnitak
fonte
Isso ignorará apenas.-Xyz - o item [] corresponde apenas ao primeiro caractere após o ponto.
2129 Hamish Downer
6
. [^.] * pegaria tudo #
falstro 02/05/09
11
... exceto coisas que começam com dois períodos.
Falstro 02/05/09
@roe - que é uma versão muito agradáveis
Alnitak
@ mish - sim, eu disse isso na resposta.
Alnitak
11

Você poderia usar rsync.

rsync -a ./ /some/other/directory/

que copiará o conteúdo do diretório atual (incluindo arquivos de ponto, mas não incluindo ..)

Rory
fonte
Simples e funciona para arquivos ocultos em pastas ocultas também.
user59183
Para mim, este é o menos confuso e mais eficaz das soluções fornecidas
palerdot
Ótima solução. Eu também precisava que ele não copiasse entre os .gitdiretórios. A adição de -C faz isso e o comando se torna:rsync -aC ./ /some/other/directory/
theruss
10

Eu te imploro, passo de expansão shell simples na cplinha de comando - expansão shell tem todos os tipos de ahem . Casos de canto "interessantes" (recursão indesejados causados por e .., espaços, coisas não-imprimíveis, hardlinks, links simbólicos, e etc.) Use em findvez disso (ele vem no findutilspacote, caso você não o tenha instalado - o que seria estranho, todas as distribuições o instalam por padrão):

find -H /path/to/toplevel/dir/ -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec cp -a '{}' /path/to/destination/dir/ \;

Explicação passo a passo:

  • -H vai causar find não siga os links simbólicos (exceto se o nome do diretório real de nível superior que você deu for um link simbólico; que será seguido.)
  • /path/to/toplevel/dir/ é, obviamente, suposto ser substituído por você pelo caminho do diretório que hospeda os arquivos de configuração e os diretórios que você deseja fazer backup.
  • -maxdepth 1 Vai parar find de recursivamente descer para qualquer diretório cujo nome comece com um ponto. Não precisamos recursar, cpfaremos isso por nós, só precisamos dos nomes nesse nível.
  • -name '.*'diz findque queremos todos os nomes que começam com um ponto. Isso não funcionará corretamente se a variável de ambiente POSIXLY_CORRECTestiver definida, mas raramente (se houver). Essa é a primeira condição de correspondência especificada até o momento.
  • a \( ....... \)é um e seguido por uma condição mais complexa entre parênteses (usei ..... para substituí-lo, é explicado abaixo.) Precisamos escapar dos parênteses, pois, caso contrário, eles serão (mis) interpretados pelo shell, daí a barra invertida na frente deles,
  • -type d -o -type f -o -type lsão três condições com um ou entre eles. -type dcorresponde aos diretórios, -type faos arquivos regulares e aos -type llinks simbólicos. Você pode selecionar o que deseja - por exemplo, se não desejar fazer backup dos diretórios de configurações, omita-type d (e -ologo atrás, obviamente).
  • -exec ..... \;diz findpara executar um comando toda vez que uma correspondência é encontrada. O final do comando é marcado por um ponto e vírgula, do qual precisamos escapar novamente com uma barra invertida para evitar a interpretação da shell. Dentro dessa linha de comando, você precisa usar {}onde deseja que o nome da correspondência encontrada atualmente termine. Como os escudos também podem interpretar mal o aparelho, você deve colocá-los em apóstrofos, como em '{}'. O comando que queremos executar neste caso é cp -a '{}' /path/to/destination/dir/(-a significa archive, que se repete em subdiretórios, copia links simbólicos como links e preserva permissões e atributos estendidos, e /path/to/destination/dir/obviamente é o nome do diretório de destino - substitua-o.)

Portanto, em inglês simples, esta findlinha de comando diz o seguinte:

Comece em / path / to / toplevel / dir /. Não desça em nenhum subdiretório. Encontre todos os diretórios, arquivos e links simbólicos cujo nome comece com um ponto. Para cada um dos encontrados, copie-o para / path / to / destination / dir / preservando a natureza, permissões e atributos estendidos.

Mihai Limbăşan
fonte
11
encontrar é a coisa mais útil de todas.
Mr. Shiny and New #
11
Boa resposta. Embora eu prefira -exec ... ';' Evitando barra invertida significa que este comando irá funcionar tanto no CLI e na crontab :))
kubanczyk
8

Eu sempre usei. ?? * para encontrar arquivos ocultos sem obter "." e "..". Pode faltar ".a" ou algo assim, mas nunca tenho um deles.

Paul Tomblin
fonte
definitivamente bonito e arrumado :) +1
falstro
Eu não quero que ele falhe misteriosamente se houver alguns ".a" s
Zifre 2/09/09
Gosto porque, se você sabe que não possui nenhum arquivo oculto de caractere único, é muito rápido digitar.
Paul Tomblin
Essa deve ser a melhor resposta. Deve ser votado para o topo.
Ibn Saeed