Tente usar o interruptor de remoção para excluir diretórios. Isso deve responder à sua pergunta:
find . -path ./your-folder -prune -o -maxdepth 1 -type d -print
Eu estou em um diretório raiz e tenho algumas pastas dentro:
0.1
0.2
0.3
0.4
0.5
0.6
shortcut -> 0.6
Eu preciso listar os diretórios acima sem o atalho, bem como a pasta 0.6. Eu não quero pesquisar acima deste local ou dentro de nenhuma dessas pastas. Eu posso ter alguns arquivos aqui também, mas preciso ignorá-los. Novas pastas com a mesma convenção de nomenclatura serão adicionadas de tempos em tempos neste diretório, portanto, essa pesquisa será incluída no script bash e gerará resultados diferentes quando novas pastas forem adicionadas e o script será executado.
Eu tentei find -P . -maxdepth 1 -type d -ls
, mas sem sorte.
Não há como saber quais nomes são os alvos dos links simbólicos, além de encontrar os links simbólicos e segui-los.
Portanto, podemos fazer isso dessa maneira (assume bash
versão 4.0 ou posterior):
#!/bin/bash
# Our blacklist and whitelist associative arrays (whitelist is a misnomer, I know)
# blacklist: keyed on confirmed targets of symbolic links
# whitelist: keyed on filenames that are not symbolic links
# nor (yet) confirmed targets of symbolic links
declare -A blacklist whitelist
for name in *; do
if [ -L "$name" ]; then
# this is a symbolic link, get its target, add it to blacklist
target=$(readlink "$name")
blacklist[$target]=1
# flag target of link in whitelist if it's there
whitelist[$target]=0
elif [ -z "${blacklist[$name]}" ]; then
# This is not a symbolic link, and it's not in the blacklist,
# add it to the whitelist.
whitelist[$name]=1
fi
done
# whitelist now has keys that are filenames that are not symbolic
# links. If a value is zero, it's on the blacklist as a target of a
# symbolic link. Print the keys that are associated with non-zeros.
for name in "${!whitelist[@]}"; do
if [ "${whitelist[$name]}" -ne 0 ]; then
printf '%s\n' "$name"
fi
done
O script deve ser executado com o diretório como o diretório de trabalho atual e não faz suposições sobre os nomes nesse diretório.
Se você quer dizer que quer todos os arquivos do tipo diretório que não são o alvo do link simbólico shortcut
, com zsh
:
#! /bin/zsh -
printf '%s\n' *(/^e'{[[ $REPLY -ef shortcut ]]}')
(...)
: qualificador glob, para filtrar os arquivos com base em outros critérios além do nome /
: somente arquivos do tipo diretório
^
: nega os seguintes qualificadores glob e'{shell code}'
: selecione arquivos com base no resultado (status de saída) da avaliação do shell code
(onde os arquivos considerados estão em $REPLY
) [[ x -ef y ]]
: retorna true se x
e y
apontarem para o mesmo arquivo (após a resolução do symlink). Normalmente, isso é feito comparando o número do dispositivo e do inode dos dois arquivos (obtidos com uma chamada de sistema stat()
que resolve os links simbólicos). Com o GNU find
(lista não ordenada, nomes de arquivo prefixados com ./
):
#! /bin/sh -
find -L . ! -name . -prune -xtype d ! -samefile shortcut
-L
: para links simbólicos, o alvo do link simbólico é considerado. Isso é necessário para que -samefile
faça a mesma coisa que zsh
' -ef
acima. ! -name . -prune
: remover qualquer arquivo, mas .
. O mesmo que -mindepth 1 -maxdepth 1
, mas mais curto e padrão. -xtype d
: agora que -L
está ativado, precisamos de -xtype
para corresponder ao tipo do arquivo original antes da resolução do link simbólico: -samefile shortcut
: true se o arquivo for igual a shortcut
(após a resolução do symlink com -L
) Para listar todos os diretórios, exceto aqueles que são o alvo de qualquer dos links simbólicos nos diretórios atuais:
#! /bin/zsh -
zmodload zsh/stat
typeset -A ignore
for f (*(N@-/)) {
zstat -H s -- $f &&
ignore[$s[device]:$s[inode]]=1
}
printf '%s\n' *(/^e'{zstat -H s -- $REPLY && ((ignore[$s[device]:$s[inode]]))}')
Observe que as zsh
-bases ignoram os arquivos ocultos. Adicione o qualificador D
glob ou defina a opção dotglob
para considerá-los.