Copia recursiva de archivos ocultos - Linux

19

¿Hay una manera fácil de copiar recursivamente todos los archivos ocultos en un directorio a otro directorio? Me gustaría hacer una copia de seguridad de todos los archivos de configuración en un directorio de inicio, no los archivos normales. Lo intenté:

cp -R .* directory

pero reconoce .y ..copia recursivamente todos los archivos no ocultos también. ¿Hay alguna manera de hacer que cp ignore .y ..?

Zifre
fuente
¿Hay alguna diferencia entre -ry -R?
Chaminda Bandara

Respuestas:

15

Mi favorito para mover directorios en general ha sido:

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

que bloquea el directorio actual para stdout luego lo canaliza a una subshell que primero los cd al directorio de destino antes de descomprimir stdin. Simple, directo, extensible: considere lo que sucede cuando reemplaza el () con un ssh a otra máquina. O para responder a su pregunta, puede hacer:

tar cvf - .* --exclude=\. --exclude=\.\. | (cd /dest/dir; tar xvf -)
pjz
fuente
1
Gracias, la opción de exclusión es lo que necesitaba. Ya lo he hecho de otra manera, pero lo guardaré para referencia futura. Esto parece realmente flexible (aunque quizás más lento).
Zifre
1
Buen consejo. Tengo un par de mejoras: 1) Uso cd /dest/dir && tar xvf -. El &&le impedirá blatting sobre el directorio de origen si tiene un error tipográfico en el destino. 2) Solo necesita el vindicador tar en uno de los comandos tar (o ninguno).
Tom Shaw
Lo suficientemente justo. También se me conoce por agrupar las cosas de la otra manera: para copiar un srcdir remoto aquí, haga(cd /src/dir && tar cf - .) | tar xvf -
pjz
17

Casi siempre, esto se puede resolver solo con:

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

Es bastante inusual tener un archivo oculto que no comienza con uno de esos personajes.

Hay otras coincidencias de patrones disponibles ( .??*, .[^.]*) - ver los comentarios

Alnitak
fuente
Eso solo ignorará.-Xyz: las cosas en [] solo coinciden con el primer carácter después del punto.
Hamish Downer
66
. [^.] * atraparía todo
falstro
1
... excepto cosas que comienzan con dos puntos.
falstro
@roe - esa es una buena versión también
Alnitak
@mish: sí, lo dije en la respuesta.
Alnitak
11

Podrías usar rsync.

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

que copiará el contenido del directorio actual (incluidos los archivos de puntos, pero no incluidos ..)

Rory
fuente
Simple, y también funciona para archivos ocultos en carpetas ocultas.
user59183 el
para mí este es el menos confuso y más eficaz de las soluciones aportadas
palerdot
Buena solución También lo necesitaba para no copiar entre .gitdirectorios. La adición de -C hace esto y lo que el comando se convierte en:rsync -aC ./ /some/other/directory/
theruss
10

Te imploro, paso de desarrollo del forro liso en la cplínea de comandos - el desarrollo del forro tiene todo tipo de ejem . Casos de esquina "interesantes" (recursividad no deseados causados por y .., espacios, cosas no imprimible, enlaces duros, enlaces simbólicos, y etc.) Use en su findlugar (viene en el findutilspaquete, en caso de que no lo tenga instalado, lo que sería extraño, todas las distribuciones lo instalan por defecto):

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/ \;

Explicación paso a paso:

  • -Hhará que findno siga los enlaces simbólicos (excepto si el nombre real del directorio de nivel superior que le dio es un enlace simbólico; eso seguirá).
  • /path/to/toplevel/dir/ obviamente, se supone que debe ser reemplazado por usted con la ruta del directorio que aloja los archivos de configuración y los directorios que desea respaldar.
  • -maxdepth 1dejará findde descender recursivamente a cualquier directorio cuyo nombre comience con un punto. No necesitamos que se repita, cplo haremos por nosotros, solo necesitamos los nombres a este nivel.
  • -name '.*'dice findque queremos todos los nombres que comienzan con un punto. Esto no funcionará correctamente si se establece la variable de entorno POSIXLY_CORRECT, pero rara vez (si es que lo está). Esta es la primera condición de coincidencia que hemos especificado hasta ahora.
  • a \( ....... \)es una y seguida de una condición más compleja entre paréntesis (he usado ..... para reemplazarlo, se explica a continuación). Necesitamos escapar de los paréntesis ya que de lo contrario el shell los interpretará (mal), de ahí la barra invertida frente a ellos,
  • -type d -o -type f -o -type lHay tres condiciones con una o entre ellas. -type dcoincide con directorios, -type fcoincide con archivos regulares y -type lcoincide con enlaces simbólicos. Puede seleccionar lo que desee, por ejemplo, si no desea hacer una copia de seguridad de los directorios de configuración, omita -type d(y el -oderecho detrás de él, obviamente).
  • -exec ..... \;le dice finda ejecutar un comando cada vez que se encuentra una coincidencia. El final del comando está marcado con un punto y coma, del que nuevamente debemos escapar con una barra diagonal inversa para evitar la interpretación de shell. Dentro de esa línea de comando, debe usar {}donde desea que termine el nombre de la coincidencia encontrada actualmente. Dado que las conchas también pueden malinterpretar las llaves, debe colocarlas en apóstrofes, como en '{}'. El comando que queremos ejecutar en este caso es cp -a '{}' /path/to/destination/dir/(-a significa archivo, que se repite en subdirectorios, copia enlaces simbólicos como enlaces y conserva los permisos y atributos extendidos, y /path/to/destination/dir/obviamente es el nombre del directorio de destino; reemplácelo).

Entonces, en inglés simple, esta findlínea de comando dice esto:

Comience en / path / to / toplevel / dir /. No descienda a ningún subdirectorio. Encuentra todos los directorios, archivos y enlaces simbólicos cuyo nombre comienza con un punto. Para cada uno de los que haya encontrado, cópielo en / path / to / destination / dir / preservando la naturaleza, los permisos y los atributos extendidos.

Mihai Limbăşan
fuente
1
encontrar es lo más útil de todos.
Mr. Shiny and New 安 宇
1
Buena respuesta. Aunque prefiero -exec ... ';' Evitar la barra invertida significa este comando funcionará tanto en CLI y en el crontab :))
kubanczyk
8

Siempre he usado. ?? * para encontrar archivos ocultos sin obtener "." y "..". Sin embargo, podría faltar ".a" o algo así, pero nunca tengo uno de esos.

Paul Tomblin
fuente
definitivamente agradable y ordenado :) +1
falstro
No quiero que falle misteriosamente si hay algunos ".a" s
Zifre
Me gusta porque si sabes que no tienes ningún archivo oculto de un solo carácter, es muy rápido escribirlo.
Paul Tomblin
Esta tiene que ser la mejor respuesta. Debería ser votado a la cima.
Ibn Saeed