Função bash recursiva (iterador de diretório)

1

Eu sei que minha tarefa a seguir pode ser realizada usando um comentário mais simples de "localizar", mas estou tentando implementar uma solução usando uma chamada recursiva. Eu estou olhando através de um diretório específico e tentando obter o comprimento máximo de qualquer nome de arquivo em todos os subdiretórios. No entanto, minha recursão funciona apenas um nível abaixo, então basicamente me retorna o nome de arquivo mais longo em um determinado diretório ou em seus subdiretórios.

#! /bin/bash

export maxlen=0

findmaxr()
{
        if [ $# -eq  0 ] ; then
        echo "Please pass arguments. Usage: findmax dir"
        exit -1
        fi

        if [ ! -d "$1" ];       then
        echo "No such directory exist."
        exit -2
        fi

        for file in $(/bin/ls $1)
                do
                if [ -d "$file" ] ; then
                        findmaxr $file   # Recursively call the method for subdirectories
                else
                        cur=${#file}
                        if [ $maxlen -lt $cur ] ; then
                                maxlen=$cur
                        fi
                fi
                done

        echo "The file with the longest name has [$maxlen] characters."



}

findmaxr 'pwd'
    
por Dani Raznikov 17.10.2016 / 04:16

1 resposta

1

Tente:

#! /bin/bash
export maxlen=0

findmaxr()
{
        if [ $# -eq  0 ] ; then
        echo "Please pass arguments. Usage: findmax dir"
        exit 1
        fi

        if [ ! -d "$1" ];       then
        echo "No such directory exist."
        exit 2
        fi

        for file in "$1"/*
                do
                if [ -d "$file" ] ; then
                        findmaxr "$file"   # Recursively call the method for subdirectories
                else
                        f=${file##*/}
                        cur=${#f}
                        if [ $maxlen -lt $cur ] ; then
                                maxlen=$cur
                        fi
                fi
                done
}

findmaxr "$PWD"
echo "The file with the longest name has [$maxlen] characters."

Discussão

Não faça isso:

for file in $(/bin/ls $1)

Mesmo que nenhum nome de arquivo contenha espaço em branco, a análise de ls ainda não é confiável.

Por outro lado, isso funcionará de forma confiável:

for file in "$1"/*

Além disso, este formulário irá manter em torno dos nomes dos diretórios pai, que é o que você precisa para descer em subdiretórios. Por exemplo, usando a estrutura de diretório no exemplo abaixo, a saída de ls mostra apenas os nomes dos arquivos para o diretório d 1 :

$ ls 'd 1'
12345  d 2

Por outro lado, a saída de 'd 1'/* inclui os nomes do diretório pai na saída:

$ echo 'd 1'/*
d 1/12345 d 1/d 2

É mantendo os nomes dos diretórios pai que fazem a recursão funcionar.

Como file agora contém o caminho completo, precisamos remover os nomes dos diretórios antes de determinarmos seu tamanho. Isso é feito com a remoção de prefixo:

f=${file##*/}

Exemplo

Considere esta estrutura de arquivos:

$ find .
.
./d 1
./d 1/12345
./d 1/d 2
./d 1/d 2/1234567
./d 1/d 2/d 3
./d 1/d 2/d 3/123456789
./script

Agora, vamos executar nosso script:

$ bash script 
The file with the longest name has [9] characters.
    
por 17.10.2016 / 04:29