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