Procura por arquivos correspondentes com curingas sem usar find em um script bash

1

Para uma tarefa, devo escrever um script bash que pode atuar como um find muito básico, mas sem usar o comando find . Por exemplo, se eu colocar esta entrada:

my_find ~/homedir/ -name 'test*' -name '*.o' -type f

Eu preciso que ele pesquise ~/homedir/ para qualquer coisa que corresponda ao nome test* com o caractere curinga, então AND e pesquise nesses resultados por qualquer coisa que corresponda a *.o name e finalmente (embora possivelmente redundante) , procure apenas por arquivos. Finalmente, listará todos os resultados.

A partir de agora, criei uma variável que armazena o caminho do diretório ( dirpath=$1 ). Em seguida, uso shift para me livrar do primeiro argumento e, em seguida, faço isso (observe que -type ainda não está implementado):

while (($#)); do
    if [[ $1 == "-name" ]]; then
        # process the name here?
        shift 2 # get rid of -name "name"
    fi
done

Eu meio que me pergunto como posso estruturar ou mesmo fazer isso. Eu tenho uma função parcialmente concluída que irá recurse através do caminho do diretório, mas eu não tenho certeza como / onde eu posso processar o argumento passado. Aqui está a função recursiva para olhar através de cada diretório.

recurse_path () {
    for i in "$@"; do
        # process and store matching file names in the array?
        if [[ -d "${i}" ]]; then
            cd "${i}"
            recurse_path *
        fi
    done
}

Então, como posso pesquisar meus nomes de arquivos correspondentes e armazenar os resultados em uma matriz enquanto uso esta função? Além disso, este é o caminho certo para fazer isso, ou há uma maneira potencialmente mais fácil de atualizar os resultados que recebo quando cada comando é visto? Sou novato no bash scripting, então gostaria de receber qualquer conselho.

    
por Alex 25.02.2015 / 10:33

2 respostas

0

deixe-me tentar apontar algo básico.

1.

se já pudermos percorrer as árvores de diretórios, a próxima coisa é pesquisar no diretório de visitantes atual. isso depende de qual estilo de sintaxe de padrão queremos suportar. regex é uma coisa totalmente diferente. talvez estejamos satisfeitos com a gramática padrão do shell. então isso vai fazer.

for i in * ; do for p in <patterns> ; do
        if [[ $i == $p ]]
        ...
        fi
done ; done

2.

para analisar a linha de comando, bash tem o getopts embutido, consulte o manual.

3.

para matrizes, consulte o manual.

    
por 25.02.2015 / 12:11
0

Uma solução suja seria parecida com:

boolRememberNext=0
rememberString=""

for arg in $*; do
   if [ ${boolRememberNext} -eq 1 ]; then
      rememberString="${rememberString} ${arg}"
   fi
   if [ "${arg}" = "-name" ]; then
      boolRememberNext=1
   else
      boolRememberNext=0
   fi
done

echo ${rememberString} | while read filemask; do
   unquotedFile=$(echo "$filemask" | tr -d "'")
   ls -R1 ~/homedir/ | grep ":" | cut -d: -f1 | while read dir; do
      ls ${dir}/unquotedFile
   done
done

Por que está sujo?

  • Muitos loops, o sistema de arquivos é acessado muitas vezes
  • A sintaxe incorreta do commmandline é ignorada
  • nomes de diretórios e arquivos podem não ter um: dentro
  • o unquoting do var com tr não manipulará * combinações
    Eu não quero usar eval para este

O que poderia ser feito para melhorar a solução?

Você pode armazenar resultados intermediários em vars locais, melhorar o manuseio de caracteres especiais e verificar a sintaxe.

Você também pode executar um ls ~/homedir/* e adicionar um asterisco ao caminho de pesquisa até que nenhum arquivo seja encontrado. Analisa todos os arquivos através de algum filtro (awk?). Verifique os arquivos que você encontra, que são arquivos, não diretórios.

    
por 27.02.2015 / 18:54