Eu preciso encontrar apenas diretórios no diretório, mas excluir um diretório vinculado e seu link

1

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.

    
por mk4965 10.08.2018 / 20:49

3 respostas

2

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
    
por 10.08.2018 / 21:11
4

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.

    
por 10.08.2018 / 21:40
3

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.

    
por 10.08.2018 / 22:35