Existe uma maneira de encontrar um arquivo em uma pesquisa recursiva inversa? [duplicado]

9

Digamos que eu esteja em um diretório que esteja dentro de uma estrutura de arquivos, como

/home/cory/projects/foo/bar/bash/baz

Eu sei que na pasta atual baz ou em uma das pastas acima eu (como home , cory , projects , foo , bar ou bash ) existe um arquivo chamado happy . Como posso encontrar esse arquivo sem pesquisar muitas pastas extras?

    
por Cory Klein 20.05.2011 / 00:32

3 respostas

19
#!/bin/bash

function upsearch () {
    test / == "$PWD" && return || test -e "$1" && echo "found: " "$PWD" && return || cd .. && upsearch "$1"
}

Esta função vai subir a partir do diretório atual. Note que é uma função e mudará o diretório enquanto estiver percorrendo. Ele irá parar no diretório, onde encontrar o arquivo, e irá até a raiz / se não.

Você pode querer alterá-lo para um script em vez de uma função e, talvez, voltar, se o arquivo não for encontrado no diretório raiz.

Se você nunca quiser fazer o cd para o diretório:

upsearch () {
  slashes=${PWD//[^\/]/}
  directory="$PWD"
  for (( n=${#slashes}; n>0; --n ))
  do
    test -e "$directory/$1" && echo "$directory/$1" && return 
    directory="$directory/.."
  done
}

Isso resultará em resultados como /home/cory/a/b/c/../../../happy se o arquivo estiver em / home / cory /. Se você precisa de um caminho limpo, você poderia fazer algumas

cd "$directory"
echo "$PWD"
cd - 

no sucesso.

    
por 20.05.2011 / 04:29
1

Dê uma olhada nas opções -mindepth e -maxdepth para find .

find não percorre diretórios em sentido inverso, mas você pode abordá-lo na direção regular e limitar a profundidade da pesquisa.

Por exemplo:

find /home /home/cory /home/cory/projects /home/cory/projects/foo /home/cory/projects/foo/bar /home/cory/projects/foo/bar/bash -maxdepth 0 -name happy -print
    
por 20.05.2011 / 00:44
1

Eu melhorei um pouco a solução @ user-unknown salvando o diretório atual, realizando um teste arbitrário e restaurando o diretório original antes de retornar com a resposta. É mais flexível porque você pode testar qualquer coisa.

Eu também forneço um segundo argumento opcional que diz o quão alto é ir.

link

#!/bin/bash

# Use this script instead of ~/.rvm/bin/rvm-prompt
# and the output of rvm-prompt will show up in your command prompt
# only if you are in a Ruby project directory.

# see http://stackoverflow.com/a/4264351/270511
# and http://unix.stackexchange.com/questions/13464/is-there-a-way-to-find-a-file-in-an-inverse-recursive-search

upsearch () {
  the_test=$1
  up_to=$2
  curdir='pwd'
  result=1

  while [[ "'pwd'" != "$up_to" && "'pwd'" != '/' ]]; do
    if eval "[[ $the_test ]]"; then
      result=0
      break
    fi
    cd ..
  done
  cd $curdir
  return $result
}

if upsearch '-e Gemfile || ! -z "$(shopt -s nullglob; echo *.gemspec *.rb)"' ; then
  ~/.rvm/bin/rvm-prompt
fi
    
por 08.01.2012 / 07:33

Tags