¿Cómo crear enlaces simbólicos a todos los archivos (clase de archivos) en un directorio?

43

Me gustaría crear enlaces simbólicos ( ln -s) a todos los archivos (o una clase de archivos, por ejemplo, terminando con .bar) en un determinado directorio. Digamos que estoy en cwd y el tipo ls ../source/*.barme da

foo.bar
baz.bar

¿Cómo puedo pasar la lista de parámetros para ln -sque finalmente se resuelva en

ln -s ../source/foo.bar
ln -s ../source/baz.bar

Por supuesto, sé que puedo escribir un script bash, pero debería haber algo más simple que implique más xargso menos, ya que parece ser una tarea común, al menos para mí.

dastrobu
fuente

Respuestas:

75

ln toma múltiples argumentos, pero no olvide dar un directorio de destino en ese caso.

Entonces, en su ejemplo .es el directorio de destino, por lo que debería ser tan fácil como

ln -s ../source/*.bar .

De man ln; el comando anterior usa la tercera forma:

ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
ln [OPTION]... TARGET                  (2nd form)
ln [OPTION]... TARGET... DIRECTORY     (3rd form)
ln [OPTION]... -t DIRECTORY TARGET...  (4th form)
  • En el primer formulario, cree un enlace a TARGET con el nombre LINK_NAME.
  • En el segundo formulario, cree un enlace a TARGET en el directorio actual.
  • En los formularios tercero y cuarto, cree enlaces a cada OBJETIVO en el DIRECTORIO.
mpy
fuente
55
Me acabas de salvar 5 minutos sólidos de mi vida, lo suficiente como para pasar uno de ellos dejando un comentario. :-)
moodboom
Esto no funciona si no hay archivos *.bar. Creará un enlace con el nombre "*.bar", que no es lo que desea.
Nimrod
1
@Nimrod: Eso es cierto, pero puedes decirle a bash que quieres que informe un error en su lugar a través de shopt -s failglob; consulte, por ejemplo, unix.stackexchange.com/a/216227/33390 (el equivalente en zsh es setopt nomatch, que está activado de forma predeterminada)
mpy
: aplausos: agradable!
Chris Schmitz
3

Utilizar find

certainDir="/path/to/dir"
find -name "*.bar" -exec ln -s {} "$certainDir" \;

Además, recuerde utilizar rutas completas (cuando sea posible) con enlaces simbólicos.

justbrowsing
fuente
2
Gracias, pero no es así find $certainDir -name "*.bar" -exec ln -s {} \;? ¿Y por qué debería usar rutas completas? Encuentro bastante conveniente saber que los enlaces permanecen intactos cuando muevo un árbol de directorios que tiene algunos enlaces internos.
dastrobu
Eso depende de dónde desea vincular los directorios. Y no puedo recordar por qué los caminos completos son una buena idea, podría haber sido por enlaces duros, pero lo recordé por alguna razón. Hmmm
justbrowsing
Gracias, tu respuesta es genial. Dado que la respuesta de mpy es la solución más simple a la pregunta, el punto es para él / ella. Aceptaría ambas respuestas, si pudiera.
dastrobu
3

Puedes probar recursivamente con el uso de globstar (bash / zsh establecido por:) shopt -s globstar:

ls -vs ../**/*.bar .

Nota: Agregado -vpara verbose.

O si la lista es demasiado larga, usando la findutilidad:

find .. -name \*.bar -exec ln -vs "{}" dest/ ';'

Esto creará enlaces dest/o lo cambiará a .la carpeta actual.

kenorb
fuente
La segunda es la respuesta correcta.
Nimrod
0

cpcon la -sopción puede crear enlaces blandos (o -lpara enlaces duros).

Desde el directorio actual se puede usar así:

$ cp -s ../path/with/scripts/* .

En tu caso será así:

$ cp -s ../source/*.bar .
cy8g3n
fuente