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.

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.

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.


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.


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 .
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.