bash рекурсивная функция для подсчета файлов - PullRequest
0 голосов
/ 19 марта 2020

Итак, я хотел создать сценарий оболочки, который подсчитывает все скрытые файлы, псевдонимы и подкаталоги в папке. Проблема в том, что рекурсивный вызов созданной мною функции не выходит за пределы первого уровня глубины go:

function recursive_func()
{
    current=$1
    echo $current
    for thing in $(ls -A $current)
    do
        if [ -d $current/$thing ]
        then
            let subd++
            recursive_func $current/$thing
        elif [ -L $thing ] ; then
            let symlinks++
        elif [ -f $thing -a ${thing:0:1} == "." ] ; then
            let hidden++
        fi
    done
}

Однако одному из моих коллег это удалось, и это выглядит так:

function recursive_func()
{
    echo $1
    for thing in $(ls -A $1)
    do
        path=$1/$thing
        if [ -d $path ]
        then
            let subd++
            recursive_func $path
        elif [ -L $path ] ; then
            let symlinks++
        elif [ -f $path-a ${thing:0:1} == "." ]; then
            let hidden++
        fi
    done
}

Я не могу сказать, почему вторая версия работает, а моя нет. Любая помощь?

Редактировать: Проблема состояла в том, что current был глобальным, и поэтому после каждого рекурсивного вызова значение было неправильным для остальных итераций в for l oop. Исправлена ​​ошибка, добавлявшая local перед current, или просто взамен $1.

Ответы [ 4 ]

1 голос
/ 19 марта 2020

Лучше использовать find, чтобы избежать рекурсивного вызова и подсчитать выходные строки с помощью w c -l.

Попробуйте выполнить поиск в папке:

find -mindepth 1 -name '.*'
find -mindepth 1 -name '.*' | wc -l
0 голосов
/ 20 марта 2020
ls -al | wc -l

Первая команда выводит список всех файлов в каталоге и помещает их в длинный формат, чтобы они занимали по одной строке каждый. Вторая команда считает строки.

Извинения; Я только что понял, что ты хотел рекурсии.

0 голосов
/ 19 марта 2020

Попробуйте это

recursive_func () {
    shopt -s dotglob
    for item in $1/*; {
        fname=$(basename $item)
        [[ -L $item ]] && ((symlinks++))
        [[ ${fname::1} = '.' ]] && ((hidden++))
        [[ -d $item ]] && { ((subd++)); recursive_func "$item"; }
    }
    shopt -u dotglob
}
0 голосов
/ 19 марта 2020

current - глобальная переменная, и после каждого рекурсивного вызова значение является неправильным для остальных итераций в for для l oop. Исправлено, добавляя local перед текущим или просто используя вместо него $ 1.

function recursive_func()
{
    local current=$1
    echo $current
    for thing in $(ls -A $current)
    do
        if [ -d $current/$thing ]
        then
            let subd++
            recursive_func $current/$thing
        elif [ -L $thing ] ; then
            let symlinks++
        elif [ -f $thing -a ${thing:0:1} == "." ] ; then
            let hidden++
        fi
    done
}

или

function recursive_func()
{
    echo $1
    for thing in $(ls -A $1)
    do
        if [ -d $1/$thing ]
        then
            let subd++
            recursive_func $1/$thing
        elif [ -L $1/$thing ] ; then
            let symlinks++
        elif [ -f $1/$thing -a ${thing:0:1} == "." ] ; then
            let hidden++
        fi
    done
}
...