Estoy tratando de crear un directorio que albergue todos y solo mis archivos PDF compilados desde LaTeX. Me gusta mantener cada proyecto en una carpeta separada, todo alojado en una carpeta grande llamada LaTeX
. Entonces intenté correr:
rsync -avn *.pdf ~/LaTeX/ ~/Output/
que debería encontrar todos los archivos PDF ~/LaTeX/
y transferirlos a la carpeta de salida. Esto no funciona Me dice que no se encontraron coincidencias para " *.pdf
". Si omito este filtro, el comando enumera todos los archivos en todas las carpetas del proyecto en LaTeX. Entonces es un problema con el filtro * .pdf. Traté de reemplazar ~/
con la ruta completa a mi directorio de inicio, pero eso no tuvo ningún efecto.
Estoy usando zsh. Intenté hacer lo mismo en bash e incluso con el filtro que enumeraba cada archivo en cada subdirectorio ... ¿Qué está pasando aquí?
¿Por qué rsync no comprende mi filtro de solo PDF?
OKAY. Así que actualiza: no, lo estoy intentando
rsync -avn --include="*/" --include="*.pdf" LaTeX/ Output/
Y esto me da la lista completa de archivos. Supongo que porque todo coincide con el primer patrón ...
**
patrón de zsh ) debería funcionar, sin embargo.Respuestas:
TL, DR:
Rsync copia las fuentes en el destino. Si pasa
*.pdf
como fuentes, el shell expande esto a la lista de archivos con la.pdf
extensión en el directorio actual. No ocurre un recorrido recursivo porque no pasó ningún directorio como fuente.Por lo tanto, debe ejecutar
rsync -a ~/LaTeX/ ~/Output/
, pero con un filtro para indicarle a rsync que.pdf
solo copie archivos. Las reglas de filtro de Rsync pueden parecer desalentadoras cuando lee el manual, pero puede construir muchos ejemplos con solo unas pocas reglas simples.Inclusiones y exclusiones:
--exclude=*~
,--exclude=/some/relative/location
(en relación con el argumento de origen, por ejemplo, se incluyen las siguientes~/LaTeX/some/relative/location
).--include=*/
) y luego excluya el resto con--exclude='*'
. Esto es porque:--include='directory/***'
lo haremos.Patrones:
/
, se aplica al nombre del archivo sin directorio./
, se aplica solo a los directorios./
, se aplica a toda la ruta desde el directorio que se pasó como argumento arsync
.*
cualquier subcadena de un solo componente de directorio (es decir, nunca coincide/
);**
coincide con cualquier subcadena de ruta.Si un argumento fuente termina con a
/
, su contenido se copia (rsync -r a/ b
creab/foo
para cadaa/foo
). De lo contrario, el directorio en sí se copia (rsync -r a b
creab/a
).Por lo tanto, aquí debemos incluir
*.pdf
, incluir directorios que los contengan y excluir todo lo demás.Tenga en cuenta que esto copia todos los directorios, incluso los que no contienen ningún archivo coincidente o subdirectorio que contenga uno. Esto se puede evitar con la
--prune-empty-dirs
opción (no es una solución universal, ya que no puede copiar un directorio ni siquiera haciendo coincidirlo explícitamente, pero ese es un requisito poco frecuente).fuente
**
patrón de zsh ), esto recrea la estructura del directorio en el directorio de destino. No estoy seguro de si esto es lo que quiere el OP .../etc/lsyncd/lsyncd.conf.lua
archivo. ¿Tienes alguna idea?El valor predeterminado es incluir todo, por lo que debe excluir explícitamente todo después de incluir los archivos que desea transferir. Elimine --dry-run para transferir realmente los archivos.
Si comienzas con:
Entonces la coincidencia codiciosa excluirá todo de inmediato.
Si intentas:
Luego, solo se transferirán los archivos pdf en la carpeta de nivel superior. No seguirá ningún directorio, ya que están excluidos por '*'.
fuente
--prune-empty-dirs
(o acceso directo-m
), incluso se ahorra muchos directorios vacíos en el destino, excepto que, por supuesto, los quiere como recordatorio o plan estructural./etc/lsyncd/lsyncd.conf.lua
archivo. ¿Tienes alguna idea?Si usa un patrón como
*.pdf
, el shell "expande" ese patrón, es decir, reemplaza el patrón con todas las coincidencias en el directorio actual. El comando que está ejecutando (en este caso rsync) desconoce el hecho de que intentó usar un patrón.Sin embargo, cuando usa zsh , hay una solución fácil: el
**
patrón se puede usar para unir carpetas de forma recursiva. Prueba esto:fuente
rsync -avn ~/LaTeX/**/*.pdf ~/Output
, pero la solución con--include
es más escalable de todos modos.**
puede ser útil en otras situaciones.cd ~/Latex && cp -p **/*.pdf ~/Output
evitar un error de "línea de comando demasiado larga".Puede usar
find
una lista intermedia de archivos (files_to_copy
) para resolver su problema. Asegúrese de estar en su directorio personal, luego:find LaTeX/ -type f -a -iname "*.pdf" > files_to_copy && rsync -avn --files-from=files_to_copy ~/ ~/Output/ && rm files_to_copy
Probado con Bash.
fuente
-exec
opción find o usarxargs
. Algo así como:find LaTeX/ -type f -iname "*.pdf" -print0 | xargs -0 -i rsync -avn {} Output/
standalone
o que no tienen un.tex
archivo con el mismo nombre, ya que estas serán imágenes incluidas en algún documento ...--files-from
acepta la lectura de stdin. Esto funcionaríafind LaTeX/ -type f -a -iname "*.pdf" | rsync -avn --files-from=- ~/ ~/Output/
A juzgar por la sección "REGLAS DE INCLUIR / EXCLUIR PATRÓN" de la página de manual , la forma de hacerlo es
La diferencia crítica entre esto y la respuesta de kbrd es la
--include="*/"
bandera, que le dice a rsync que continúe y copie los directorios que encuentre, como se llamen. Esto es necesario porque rsync no se repetirá en un subdirectorio a menos que se le indique que copie ese subdirectorio.Además, tenga en cuenta que las comillas evitan que el shell intente expandir los patrones a los nombres de archivos en relación con el directorio actual y realice una de las siguientes acciones:
Tener éxito y estropear su filtro (no es muy probable que esté en medio de una bandera como esa, aunque realmente nunca se sabe cuándo alguien creará un archivo llamado
--include=foo.pdf
...)Fallando, y potencialmente produciendo un error en lugar de ejecutar el comando (como descubrió que zsh lo hace por defecto).
fuente
include
agregar cosas adicionales que ya están allí no cambia nada. Si ves a lo que me refiero ...--exclude="*"
después del--include="*.pdf"
, o esto transferirá todo.Qué tal esto:
fuente
man rsync
coloca el filtro después de las opciones y antes de la fuente / destino. Intenté esto y no funcionóa
opción es para archivo y, entre otras cosas, hace que la copia sea recursiva.Aquí hay algo que debería funcionar sin usar find. La diferencia con las respuestas ya publicadas es el orden de las reglas de filtro. Las reglas de filtro en un comando rsync funcionan de manera muy parecida a las reglas de iptable, la primera regla que coincide con un archivo es la que se usa. Desde la página del manual :
Por lo tanto, necesita un comando de la siguiente manera:
Tenga en cuenta el patrón "**. Pdf". Según la página del manual :
En mi pequeña prueba, esto funciona recursivamente en el árbol de directorios y solo selecciona los archivos PDF.
fuente
*.pdf
en el directorio de nivel superior (pero no~/LaTeX/foo/bar.pdf
).**
. Sería bueno tener un ejemplo de ello. ;)Esta es mi solución preferida:
El
find
comando es más fácil de entender que las reglas de inclusión / exclusión dersync
:-)Si desea copiar solo archivos PDF, simplemente cambie
.jpg
a.pdf
fuente