¿Cómo copiar archivos y subdirectorios ocultos (comenzando con un punto) en Linux?


10

¿Cómo copiar archivos ocultos y subdirectorios ocultos (los que comienzan con un punto) en la carpeta A a la carpeta B? Por ejemplo si tengo esta estructura:

A/a
A/b
A/.a
A/.b/
A/.b/somefile
A/.b/.c

Me gustaría copiar a B solo los archivos ocultos y los subdirectorios ocultos en A:

B/.a
B/.b/
B/.b/somefile
B/.b/.c

Ya probé este comando: cp A/.* Bde esta otra pregunta de superusuario . Sin embargo, no copia los subdirectorios. También lo intenté cp -r A/.* B, pero se copia, .así que termino con una copia exacta de A (incluidos los archivos normales). Cualquier ayuda es apreciada.

Respuestas:


16

Siempre y cuando solo esté buscando archivos y carpetas ocultos en el nivel de A y no desee, por ejemplo

A/b/.hidden

para ser copiado, deberías poder usar esto:

cp -r A/.[^.]* B

Básicamente significa copiar todo lo que comienza con ay .luego cualquier carácter que no sea un .que se filtra .y..

Editar: se eliminó el -p del comando cp ya que Asker no ha indicado que quiere preservar ninguna propiedad, fecha, etc.


Esto funciona para los nombres de archivo y directorio de ejemplo dados en la pregunta, pero el texto de la pregunta dice "archivos ocultos y subdirectorios ocultos (los que comienzan con un punto)", y esta respuesta no encontrará archivos y directorios cuyos nombres comiencen con dos puntos por ejemplo, ..c.
— Scott

Es un caso bastante marginal, pero una preocupación legítima, no obstante. No lo había considerado. Podrías dar cuenta de eso cambiando a, .*[^.]pero luego te perderías los archivos que terminan en a .. Creo que, de hecho, necesitaría un globbing extendido para realmente explicar todos los casos.
— Omnipresencia

4

El problema con A/.*es que existe el directorio .en el Aque también coincide con el patrón.

Puede activar patrones de glob extendido y usar lo siguiente:

shopt -s extglob
cp -r A/.!(?(.)) B    

Coincide con los archivos cuyo nombre comienza con un punto y cuyo segundo carácter no es ni un punto ni nada (? (.) No coincide con nada o un punto,! (...) lo niega, es decir! (? (.)) Coincide con todo lo demás que nada o un punto).


+1 para una respuesta correcta. Tenga en cuenta que .!(@(|.))es (AFAICT) equivalente al anterior, (IMNSHO) un poco más claro y solo un carácter más.
— Scott

3

Para casos como este recomendaría usar en findlugar de cpesto:

find A/ -type f -maxdepth 1 -name '.*' -exec cp -p {} B/ \;

La sintaxis básica se desglosa así:

  • find A/ -type f: findelementos en el directorio A/cuyo tipo es un archivo (en lugar de un directorio) ...
  • -maxdepth 1 -name '.*': Para esto para un maxdepthde 1 directorios y cuyo namecomienza con ..
  • -exec cp -p {} B/ \;: Y una vez que se encuentran estos archivos, execel cpcomando con una -pbandera para preservar fechas / horas desde el origen ( {}) hasta el destino de B/.

Me gusta usar maxdepthpara agregar una capa de control, así que no estoy copiando accidentalmente un sistema de archivos completo. Pero siéntase libre de eliminar eso.


0
 for item in `find A -type d | grep -E "\."` ; do cp -r $item B ; done
  • find A -type d proporciona una lista recursiva dentro de A con solo directorios
  • grep -E "\." filtra los directorios con un punto (es decir, directorios ocultos)
  • la opción -E era necesaria aquí porque sin ella también significa "directorio actual"
  • la barra invertida es evitar el significado, bajo regexp, de "cualquier personaje"
  • cp -r copiar recursivamente

Creé la estructura de archivos y carpetas para A y ejecuté el comando en Git Bash (no estoy con un Linux en este momento) y funcionó.


Esto se rompe si los archivos tienen espacios en blanco o caracteres especiales en su nombre o ruta.
— slhck

Gracias por notar :) En realidad me limité al "caso de prueba" de @gaboroncancio. Si usted me puede dar otra batería de pruebas que pueden tratar de mejorar eso (por supuesto, si usted quiere, mejorar por sí mismo, ya sea editando esta respuesta o la creación de una nueva respuesta)
— malarres

Simplemente podría poner los archivos de puntos en una carpeta llamada A B, y luego actuaría inesperadamente porque se expandiría a cp -r A B/.dotfile B. El consejo general es no analizar findo lsgenerar en absoluto. Si usa find, también debe usar sus propias opciones para filtrar en lugar de grep, y si canaliza la findsalida en otro lugar, use -print0o llame directamente al comando que desee. Ver el find manual .
— slhck

Incluso de manera más general, cuando se trabaja con archivos, es más seguro usar globs de shell como se explica en otras respuestas (aunque a menudo requieren extglobser configurados).
— slhck

Gracias por el enlace. Dejemos el findanálisis entonces.
— malarres

0

Como alternativa, puede usar este otro comando si el segundo carácter es alfanumérico ( fuente ):

cp -r A/.[a-zA-Z0-9]* B

Esto funciona para los nombres de archivo y directorio de ejemplo dados en la pregunta, pero el texto de la pregunta dice "archivos ocultos y subdirectorios ocultos (los que comienzan con un punto)", y esta respuesta no encontrará archivos y directorios cuyos nombres comiencen con un punto y un caracter especial; por ejemplo, .@fooo ..c.
— Scott

Es por eso que señalo que funciona si el segundo carácter es alfanumérico. ;)
— gaboroncancio
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.