Como criar links simbólicos para todos os arquivos (classe de arquivos) em um diretório?

43

Eu gostaria de criar links simbólicos ( ln -s) para todos os arquivos (ou uma classe de arquivos, por exemplo, terminando com .bar) em um determinado diretório. Diga que estou no cwd e tipo ls ../source/*.barme dá

foo.bar
baz.bar

como posso passar a lista de parâmetros para ln -sque finalmente resolva

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

É claro que sei que posso escrever um script bash, mas deve haver algo mais simples que envolva xargsisso, pois parece ser uma tarefa comum - pelo menos para mim.

dastrobu
fonte

Respostas:

75

ln usa vários argumentos, mas não se esqueça de fornecer um diretório de destino nesse caso.

Portanto, no seu exemplo .é o diretório de destino, deve ser tão fácil quanto

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

De man ln; o comando acima usa o terceiro formulário:

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)
  • No 1º formulário, crie um link para TARGET com o nome LINK_NAME.
  • No segundo formulário, crie um link para TARGET no diretório atual.
  • Nos 3º e 4º formulários, crie links para cada ALVO no DIRETÓRIO.
mpy
fonte
5
Você acabou de me salvar 5 minutos sólidos da minha vida, vale o suficiente para gastar um deles deixando um comentário. :-)
moodboom 24/03
Isso não funciona se não houver arquivos *.bar. Ele criará um link com o nome "*.bar", que não é o que você deseja.
Nimrod
1
@ Nimrod: Isso é verdade, mas você pode dizer ao bash que deseja que ele relate um erro em vez disso shopt -s failglob; ver, por exemplo unix.stackexchange.com/a/216227/33390 (O equivalente em zsh é setopt nomatch, que está ligado por padrão)
mpy
: palmas: legal!
Chris Schmitz
3

Usar find

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

Além disso, lembre-se de usar caminhos completos (sempre que possível) com links simbólicos.

só navegando
fonte
2
Obrigado, mas não é find $certainDir -name "*.bar" -exec ln -s {} \;? E por que devo usar caminhos completos? Acho conveniente saber que os links permanecem intactos quando movo uma árvore de diretórios pelo qual há alguns links internos.
Dastrobu
That depends where you want to symlink the directories. And I can't remember why full paths are a good idea, it might have been for hard links but I burned that into my mind for a reason. Hmmm.
justbrowsing
Obrigado, sua resposta é ótima. Como a resposta de mpy é a solução mais simples para a pergunta, o ponto vai para ele / ela. Eu aceitaria as duas respostas, se pudesse.
Dastrobu
3

Você pode tentar recursivamente usando globstar (bash / zsh definido por:) shopt -s globstar:

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

Nota: Adicionado -vpara detalhado.

Ou se a lista for muito longa, usando o findutilitário:

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

Isso criará links dest/ou alterará .para a pasta atual.

kenorb
fonte
O segundo é a resposta correta.
Nimrod
0

cpcom a -sopção pode criar links flexíveis (ou -lpara links físicos).

Do diretório atual pode ser usado assim:

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

No seu caso, será assim:

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