Copiando recursivamente arquivos ocultos - Linux

16

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

cp -R .* directory

mas reconhece . e .. e recursivamente copia todos os arquivos não ocultos também. Existe uma maneira de fazer com que o cp ignore . e .. ?

    
por Zifre 02.05.2009 / 18:35

6 respostas

14

O meu favorito para mover dirs em geral foi:

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

que transforma o diretório atual em stdout, em seguida, canaliza para um subshell que primeiro cd's para o diretório de destino antes de untarring 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 -)
    
por 05.05.2009 / 22:43
17

Quase toda vez que isso pode ser resolvido apenas com:

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

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

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

    
por 02.05.2009 / 18:40
11

Você pode usar rsync .

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

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

    
por 21.01.2010 / 16:31
10

Eu lhe imploro, afaste-se da expansão de shell simples na linha de comando cp - a expansão de shell tem todos os tipos de casos de ângulos "interessantes" (recursão indesejada causada por. e .., espaços, material não imprimível, hardlinks, links simbólicos, e assim por diante.) Use find (ele vem no pacote findutils , caso você não o tenha instalado - o que seria estranho, todas as distribuições são instaladas 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 will cause find not to follow symlinks (except if the actual toplevel directory name you gave it is a symlink; that it will follow.)
  • /path/to/toplevel/dir/ is, obviously, supposed to be replaced by you with the path do the directory which hosts the settings files and directories you want to back up.
  • -maxdepth 1 will stop find from recursively descending into any directories whose name starts with a dot. We don't need it to recurse, cp will do that for us, we just need the names at this level.
  • -name '.*' tells find that we want all names that start with a dot. This won't work correctly if the environment variable POSIXLY_CORRECT is set, but it rarely (if ever) is. This is the first match condition we have specified so far.
  • a \( ....... \) is an and followed by a more complex condition in parentheses (I've used ..... to replace it, it's explained below.) We need to escape the parentheses since they'll otherwise be (mis)interpreted by the shell, hence the backslash in front of them,
  • -type d -o -type f -o -type l are three conditions with an or between them. -type d matches directories, -type f matches regular files, and -type l matches symlinks. You can select what you want - for example, if you don't want to backup settings directories, omit -type d (and the -o right behind it, obviously.)
  • -exec ..... \; tells find to execute a command every time a match is encountered. The end of the command is marked by a semicolon, which we again need to escape with a backslash to avoid shell interpretation. Within that command line, you need to use {} where you want the name of the currently encountered match to end up. Since shells might also misinterpret the curly braces, you should place them in apostrophes, as in '{}'. The command we want to execute in this case is cp -a '{}' /path/to/destination/dir/ (-a means archive, which recurses in subdirectories, copies symlinks as links, and preserves permissions and extended attributes, and /path/to/destination/dir/ is obviously the name of the destination directory - replace it.)

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

Start at /path/to/toplevel/dir/. Do not descend into any subdirectories. Find all directories, files and symlinks whose name starts with a dot. For each of those you have found found, copy it to /path/to/destination/dir/ preserving nature, permissions, and extended attributes.

    
por 02.05.2009 / 21:36
8

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

    
por 02.05.2009 / 18:44
0

Respostas muito melhores aqui; link

Descreve, por exemplo, usando shopt para uma solução bash nativa

    
por 01.06.2016 / 10:33