Se você quiser criar links simbólicos de $HOME/this , $HOME/there/that , $HOME/Data/ddd etc., mas não $HOME/Data ou $HOME/somewhere/Labs , os critérios de correspondência devem ser
find "$HOME" ! \( -name Data -o -name Labs \) -exec …
Você estava com parênteses faltando. A justaposição liga-se mais do que -o , então -name Data -o name Labs -exec … executa o comando para arquivos denominados Labs apenas (exceto para arquivos denominados Data , mas nenhum deles também pode receber o nome Labs ).
Se você quis excluir todos os arquivos em Data e Labs , precisará da ação -prune , que diz a find para ignorar completamente os diretórios, sem percorrê-los recursivamente.
find "$HOME" \( -name Data -o -name Labs \) -prune -o -exec …
Isso exclui qualquer subárvore cuja raiz seja chamada Data , não apenas $HOME/Data . Se você quiser excluir apenas $HOME/Data , mas não, por exemplo, $HOME/sub/data , você pode usar -path (se sua implementação find for compatível).
find "$HOME" \( -path "$HOME/Data" -o -path "$HOME/Labs" \) -prune -o -exec …
Agora, para a parte -exec . Em uma ação -exec , use {} (em um argumento próprio) para representar o caminho que find encontrou. Coloque um ; (citado para que seja passado para find e não seja analisado pelo shell) no final do comando para ser executado.
find … -exec ln -s {} "$HOME/Documents/" \;
Se você apenas deseja os arquivos diretamente em $HOME e não os arquivos em subdiretórios, então find não é a melhor ferramenta para o trabalho: ele foi projetado para navegação recursiva. Use um loop de shell. Observe que o padrão * ignora os arquivos de ponto, ou seja, todos os arquivos cujo nome começa com . e o padrão .* corresponde a todos os arquivos de pontos mais . e .. , esses dois devem ser ignorados explicitamente.
for x in ~/* ~/.*; do
case "${x##*/}" in
.|..|Data|Labs) continue;; # Skip those entries
esac
ln -s "$x" "$HOME/Documents";;
done