URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9921
[ Назад ]

Исходное сообщение
"Рекурсивный обход поддерикторий"

Отправлено CROSP , 18-Окт-14 16:26 
Здравствуйте, вот уже который час пытаюсь сделать простенький скрипт, но не выходит. На любом языке программирования без проблем бы сделал, а со скриптом что-то не получается, видно что-то не так понял в синтаксисе. Никак не могу сделать.
Нужно сделать такой скрипт который начиная от текущей директории идет рекурсивно по папкам и считает количество файлов в каждой из них. Если количество файлов больше 10, то добавляется в файл с именем BigList, иначе в ShortList.
Мой скрипт работает как попало. Видно что я что-то с переменными сделал, что при выходе из рекурсии переменные не имеет того же значения что и до рекурсии.
Нужно сделать скрипт без использования других команд, таких как find и так далее.
Вот собственно сам скрипт.
Подскажите пожалуйста что не так.
#!/bin/bash
parent_dir=""
if [ -d "$1" ]; then
    path=$1;
else
    path=$(pwd)
fi
parent_dir=$path
loop_folder_recurse() {
    local files_list=""      
    local cnt=0
    for i in "$1"/*;do
        if [ -d "$i" ];then
            echo "dir: $i"
            parent_dir=$i              
            echo before recursion
            loop_folder_recurse "$i"
            echo after recursion
            if [ $cnt -ge 10 ]; then
                echo -e "---"$parent_dir >> BigList
                echo -e $file_list >> BigList
            else
                echo -e "---"$parent_dir >> ShortList
                echo -e $file_list >> ShortList
            fi
        elif [ -f "$i" ]; then
            echo file $i
            if [ $cur_fol != $main_pwd ]; then
                file_list+=$i'\n'
                cnt=$((cnt + 1))
            fi
        fi
    done
}
echo "Base path: $path"
loop_folder_recurse $path

Содержание

Сообщения в этом обсуждении
"Рекурсивный обход поддерикторий"
Отправлено Аноним , 18-Окт-14 17:37 
#!/bin/sh

NUM=10
BIG_LIST="${HOME}/BigList";
SHORT_LIST="${HOME}/ShortList";

discover() {
    cd "${1}";
    DIR="${PWD}";

    for FILE in .* *; do
        if [ -d "${FILE}" ]; then
            # Включая директории.
            # COUNT=$((${COUNT:-0}+1));
            (discover "${FILE}");
        else
            COUNT=$((${COUNT:-0}+1));
        fi
    done
    
    if [ "${COUNT:-0}" -gt "${NUM}" ]; then
        echo "${DIR}" >> "${BIG_LIST}";
    else
        echo "${DIR}" >> "${SHORT_LIST}";
    fi
}

# Если нужно объяснить (что-то ещё) - обращайтесь.


if [ -z "${*}" ]; then
    set "${PWD}";
fi

for DIR in ${@}; do
    if [ ! -e "${DIR}" ]; then
        echo 1>&2 "${DIR}: No such file ir directory";
        continue;
    fi
    
    if [ ! -d "${DIR}" ]; then
        echo 1>&2 "${DIR} is a file, not a directory";
        continue;
    fi
    
    (discover "${DIR}");    
    
done


"Рекурсивный обход поддерикторий"
Отправлено CROSP , 18-Окт-14 21:47 
>[оверквотинг удален]
>  if [ ! -e "${DIR}" ]; then
>   echo 1>&2 "${DIR}: No such file ir directory";
>   continue;
>  fi
>  if [ ! -d "${DIR}" ]; then
>   echo 1>&2 "${DIR} is a file, not a directory";
>   continue;
>  fi
>  (discover "${DIR}");
> done

Спасибо большое за ответ, но не понял , как Вы сделали. И скрипт не работает, входит в вечный цикл порождения новых процессов.
Объясните пожалуйста Вашу идею. Спасибо еще раз


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 18-Окт-14 22:12 
Fix.
#!/bin/sh

NUM=10
BIG_LIST="${HOME}/BigList";
SHORT_LIST="${HOME}/ShortList";

discover() {
    cd "${1}";
    DIR="${PWD}";

    for FILE in .* *; do
        if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
            continue;
        fi

        if [ -d "${FILE}" ]; then
            # Включая директории.
            # COUNT=$((${COUNT:-0}+1));
            if [ ! -r "${FILE}" ]; then
                echo 1>&2 "${FILE}: no read permission on file";
            else
                (discover "${FILE}");
            fi
        else
            COUNT=$((${COUNT:-0}+1));
        fi
    done
    
    if [ "${COUNT:-0}" -gt "${NUM}" ]; then
        echo "${DIR}" >> "${BIG_LIST}";
    else
        echo "${DIR}" >> "${SHORT_LIST}";
    fi
}

if [ -z "${*}" ]; then
    set "${PWD}";
fi

for DIR in ${@}; do
    if [ ! -e "${DIR}" ]; then
        echo 1>&2 "${DIR}: No such file ir directory";
        continue;
    fi
    
    if [ ! -d "${DIR}" ]; then
        echo 1>&2 "${DIR} is a file, not a directory";
        continue;
    fi
    
    (discover "${DIR}");    
    
done


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 18-Окт-14 23:47 
Fix.
#!/bin/sh

NUM=10
BIG_LIST="${HOME}/BigList";
SHORT_LIST="${HOME}/ShortList";

discover() {
    cd "${1}";
    DIR="${PWD}";

    for FILE in .* *; do
        if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
            continue;
        fi

        if [ -d "${FILE}" ]; then
            # Включая директории.
            # COUNT=$((${COUNT:-0}+1));
            if [ ! -x "${FILE}" ]; then
                echo 1>&2 "${FILE}: no execute (or search) permission on file";
            else
                (discover "${FILE}");
            fi
        else
            COUNT=$((${COUNT:-0}+1));
        fi
    done
    
    if [ "${COUNT:-0}" -gt "${NUM}" ]; then
        echo "${DIR}" >> "${BIG_LIST}";
    else
        echo "${DIR}" >> "${SHORT_LIST}";
    fi
}

if [ -z "${*}" ]; then
    set "${PWD}";
fi

for DIR in "${@}"; do
    if [ ! -e "${DIR}" ]; then
        echo 1>&2 "${DIR}: No such file ir directory";
        continue;
    fi
    
    if [ ! -d "${DIR}" ]; then
        echo 1>&2 "${DIR} is a file, not a directory";
        continue;
    fi
    
    (discover "${DIR}");    
    
done

Проверяем, были ли переданы параметры скрипту.
if [ -z "${*}" ]; then
    set "${PWD}";
fi

${*} - все позиционные параметры одной строкой
$ script.sh a b c
«a» - первый позиционный параметр, $1.
«b» - второй позиционный параметр, $2.
«c» - третий позиционный параметр, $3.
$ a() { echo "\$1 = $1, \$2 = $2, \$3 = $3, \$* = $*"; }
$ a a b c

Если строка пустая, то это означает, что скрипту не были переданы параметры
$ a() { if [ -z "${var}" ]; then  echo "var is empty"; else echo "var is $var"; fi }
$ a
$ var="text"
$ a
$ unset var
$ a


Логичнее использовать
if [ $# -gt 0 ]; then
    …
fi

$# - количество позиционных параметров.


Если скрипту не переданы параметры, то сохраняем абсолютный путь к текущей директории в первом позиционном параметре.

# Удалим все позиционные параметры.
$ shift $#
$ if [ -z "${1}" ]; then  echo "\$1 is empty"; else echo "\$1 is $1"; fi
$ set "${PWD}"
$ if [ -z "${1}" ]; then  echo "\$1 is empty"; else echo "\$1 is $1"; fi


Переменная $PWD всегда содержит абсолютный путь к текущей директории.
Нет необходимости выполнять команду pwd.

for DIR in "${@}"; do
    …
done

Сохраняем (поочерёдно) значение каждого позиционного параметра в переменную DIR.
$ set /tmp/dir "/tmp/d i r" /tmp
$1 - /tmp/dir
$2 - /tmp/d i r
$3 - /tmp

$ for DIR in "${@}"; do echo "\$DIR id ${DIR}"; done

"${@}" - экранируется (цитируется, ориг. quoting), поскольку в именах директорий (файлов) могут содержаться «специальные символы» (например, пробелы).

Сравните результат.
$ set /tmp/dir "/tmp/d i r" /tmp
$ for DIR in "${@}"; do echo "\$DIR id ${DIR}"; done
$ for DIR in ${@}; do echo "\$DIR id ${DIR}"; done


Проверяем, существует ли файл.

    if [ ! -e "${DIR}" ]; then
        echo 1>&2 "${DIR}: No such file ir directory";
        continue;
    fi


Вывод сообщения об ошибке:

echo 1>&2 "${DIR}: No such file ir directory";

перенаправляем в stderr (поток номер 2).

То есть, если файл не существует, то выводим сообщение об ошибке и возвращаемся (при помощи оператора continue) в начало цикла (переменной DIR присваивается значение следующего позиционного параметра.

    
Проверяем, является ли файл директорией.

    if [ ! -d "${DIR}" ]; then
        echo 1>&2 "${DIR} is a file, not a directory";
        continue;
    fi

Если файл не является директорией, то нам не нужно его обрабатывать, ведь нам нужно «посчитать количество файлов в каждой директории».

То есть если скрипту в качестве параметры передан файл, а не директория, то мы сообщаем об этом и переходим к следующему параметру.

Вызываем функцию discovery в subshell, передав значение переменной DIR.
$ a() { echo "\$1 is $1"; }
$ a /tmp

Нужно использовать «экранирование».
Сравните результат.
$ a() { echo "\$1 is $1"; }
$ a "/tmp/d i r"
$ a /tmp/d i r

Нам нужен отдельный счётчик для каждой директории, для этого мы используем subshell (В bash, можно использовать массив).

Сравните результат.
$ a() { var="$1"; echo "var is $var"; }
$ unset var
$ echo $var
$ (a text)
$ echo $var
$ a text
$ echo $var


discover() {
    # Переходим в директорию.
    cd "${1}";

    DIR="${PWD}";

    # Сохраняем (поочерёдно) имя каждого файла (в директории) в переменную FILE.
    # Нам нужно обработать все файлы, в том числе и скрытые.
    # Сравните результат.
    # $ mkdir /tmp/dir
    # $ touch /tmp/dir/.file
    # cd /tmp/dir
    # $ ls .*
    # $ ls *
    for FILE in .* *; do
        # Игнорируем родительский каталог ".."
        # Игнорируем «синоним» для текущей директории "."
        # $ mkdir /tmp/dir
        # $ cd /tmp/dir
        # «..» - /tmp
        # «.» - /tmp/dir
        # Если значение переменной FILE равно «..» или «.»
        if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
            # Переходим к следующим файлу (возвращаемся в начала цикла).
            continue;
        fi

        # Проверяем, является ли файл директорией.
        if [ -d "${FILE}" ]; then
            # Включая директории.
            # COUNT=$((${COUNT:-0}+1));
            # Проверяем, есть ли у текущего пользователя право на выполнение (поиск), если нет, то мы не сможем в неё перейти.
            if [ ! -x "${FILE}" ]; then
                echo 1>&2 "${FILE}: no execute permission on file";
            else
                (discover "${FILE}");
            fi
        else
            # Инкрементируем счётчик.
            # Если, переменная COUNT не имеет значения, то подставляем 0.
            COUNT=$((${COUNT:-0}+1));
        fi
    done
    
    # Если значение счётчика больше значения переменной NUM.
    if [ "${COUNT:-0}" -gt "${NUM}" ]; then
        echo "${DIR}" >> "${BIG_LIST}";
    else
        echo "${DIR}" >> "${SHORT_LIST}";
    fi
}



"Рекурсивный обход поддерикторий"
Отправлено Аноним , 19-Окт-14 00:08 
Fix.

#!/bin/sh

NUM=10
BIG_LIST="${HOME}/BigList";
SHORT_LIST="${HOME}/ShortList";

discover() {
    cd "${1}";
    
    # На случай, если по каким-либо причинам не удаётся перейти в диреторию.
    if [ $? -ne 0 ]; then
        echo 1>&2 "Cannot change working directory to ${1}";
        return 1;
    fi
    
    DIR="${PWD}";

    for FILE in .* *; do
        if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
            continue;
        fi

        if [ -d "${FILE}" ]; then
            # Включая директории.
            # COUNT=$((${COUNT:-0}+1));
            if [ ! -x "${FILE}" ]; then
                echo 1>&2 "${FILE}: no execute (or search) permission on file";
            else
                (discover "${FILE}");
            fi
        else
            COUNT=$((${COUNT:-0}+1));
        fi
    done
    
    if [ "${COUNT:-0}" -gt "${NUM}" ]; then
        echo "${DIR}" >> "${BIG_LIST}";
    else
        echo "${DIR}" >> "${SHORT_LIST}";
    fi
}

if [ -z "${*}" ]; then
    set "${PWD}";
fi

for DIR in "${@}"; do
    if [ ! -e "${DIR}" ]; then
        echo 1>&2 "${DIR}: No such file ir directory";
        continue;
    fi
    
    if [ ! -d "${DIR}" ]; then
        echo 1>&2 "${DIR} is a file, not a directory";
        continue;
    fi
    
    (discover "${DIR}");    
    
done


"Рекурсивный обход поддерикторий"
Отправлено тень_pavel_simple , 19-Окт-14 09:41 
>[оверквотинг удален]
>  if [ ! -e "${DIR}" ]; then
>   echo 1>&2 "${DIR}: No such file ir directory";
>   continue;
>  fi
>  if [ ! -d "${DIR}" ]; then
>   echo 1>&2 "${DIR} is a file, not a directory";
>   continue;
>  fi
>  (discover "${DIR}");
> done

За /bin/sh и несоответствие ниженаписанному нужно бить, используя баш нужно в качестве интертпритатора его и указывать.

И спасибо за светлое будущие.


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 19-Окт-14 13:01 
> За /bin/sh и несоответствие ниженаписанному нужно бить, используя баш нужно в качестве
> интертпритатора его и указывать.
> И спасибо за светлое будущие.

Бить Вас?
К Вашему будущему я не имею отношения.
Что и чему не соответствует? Пожалуйста, поясните!
Если сочтёте полезным, ознакомьтесь с Posix стандартом, пожалуйста!

Я постарался (хотя бы кратко), объяснить что и для чего делается (буду рад услышать аргументы).


"Рекурсивный обход поддерикторий"
Отправлено CROSP , 19-Окт-14 13:36 
>[оверквотинг удален]
>  if [ ! -e "${DIR}" ]; then
>   echo 1>&2 "${DIR}: No such file ir directory";
>   continue;
>  fi
>  if [ ! -d "${DIR}" ]; then
>   echo 1>&2 "${DIR} is a file, not a directory";
>   continue;
>  fi
>  (discover "${DIR}");
> done

Спасибо ВАМ огромное за помощь и объяснения, вроде все понял, только один момент еще, в кода написал.
И подскажите пожалуйста, все равно скрипт добавляет в файл BigList папки где меньше 10 файлов. Я вот тут дописал вывод файлов для каждой директории.
Подскажите пожалуйста из-за чего так. Еще такой момент тут с переменными как-то не так как обычно привык. До того как сделал переменную FILE_STR локальной, выводило список повторяющихся файлов по пути обхода. Соответственно поэтому и попадает в BigList.Подскажите что тут не так и спасибо еще раз.
#!/bin/bash
NUM=10
BIG_LIST="${PWD}/BigList";
SHORT_LIST="${PWD}/ShortList";
discover() {
    cd "${1}";
    
    # На случай, если по каким-либо причинам не удаётся перейти в диреторию.
    if [ $? -ne 0 ]; then
        echo 1>&2 "Cannot change working directory to ${1}";
        return 1;
    fi
    
    DIR="${PWD}";

    for FILE in .* *; do
        if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
            continue;
        fi

        if [ -d "${FILE}" ]; then
            # Включая директории.
            # COUNT=$((${COUNT:-0}+1));
            if [ ! -x "${FILE}" ]; then
                echo 1>&2 "${FILE}: no execute (or search) permission on file";
            else
                (discover "${FILE}");
            fi
        else
    COUNT=$((${COUNT:-0}+1));
   local FILE_STR+='file : '$FILE'\n';
        fi
    done
    
    if [ "${COUNT:-0}" -gt "${NUM}" ]; then
        echo "${DIR}" >> "${BIG_LIST}";
    echo -e "${FILE_STR}" >> "${BIG_LIST}";
    FILE_STR="";
    else
        echo "${DIR}" >> "${SHORT_LIST}";
    echo -e "${FILE_STR}" >> "${SHORT_LIST}";
    FILE_STR="";
    fi
}
#Если есть хоть один аргумент командного файла
if [ -z "${*}" ]; then
#Если нету, то устанавливаем текущий каталог. В какую переменную ?  
set "${PWD}";
fi
rm BigList
rm ShortList
# Что означает символ @ в данном случае ? первую переменную ?
for DIR in "${@}"; do
    if [ ! -e "${DIR}" ]; then
        echo 1>&2 "${DIR}: No such file ir directory";
        continue;
    fi
    
    if [ ! -d "${DIR}" ]; then
        echo 1>&2 "${DIR} is a file, not a directory";
        continue;
    fi
    
    (discover "${DIR}");    
    
done


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 19-Окт-14 14:14 
> И подскажите пожалуйста, все равно скрипт добавляет в файл BigList папки где
> меньше 10 файлов.

Нужен пример (с использованием оригинального скрипта).

> Еще такой момент тут с переменными как-то не так как обычно привык.

Не забывайте, в моём скрипте, каждая директория обрабатывается в subshell (переменные «изолированы»).

> #Если нету, то устанавливаем текущий каталог. В какую переменную ?
>  set "${PWD}";

Цитирую.
Если скрипту не переданы параметры, то сохраняем абсолютный путь к текущей директории в первом позиционном параметре.

# Удалим все позиционные параметры.
$ shift $#
$ if [ -z "${1}" ]; then  echo "\$1 is empty"; else echo "\$1 is $1"; fi
$ set "${PWD}"
$ if [ -z "${1}" ]; then  echo "\$1 is empty"; else echo "\$1 is $1"; fi


> # Что означает символ @ в данном случае ? первую переменную ?

Все позиционные параметры.
"$@" - "${1}" "${2}" ... "${n}"
http://citforum.ru/programming/shell/gl4.shtml
http://www.ibm.com/developerworks/ru/library/l-bash-parameters/
Следующие конструкции «одинаковы».
for var in "${@}"; do
    ...
done

for var in "${1}" "${2}" ... "${n}"; do
    ...
done


Касательно скрипта (по результатам) на форуме.
За объяснением (и прочим) - http://pastebin.com/MT4V3qdv


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 19-Окт-14 14:32 
Fix.

#!/bin/sh

NUM=10
BIG_LIST="${HOME}/BigList";
SHORT_LIST="${HOME}/ShortList";

discover() {
    cd "${1}";
    unset COUNT;
    
    # На случай, если по каким-либо причинам не удаётся перейти в диреторию.
    if [ $? -ne 0 ]; then
        echo 1>&2 "Cannot change working directory to ${1}";
        return 1;
    fi
    
    DIR="${PWD}";

    for FILE in .* *; do
        if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
            continue;
        fi

        if [ -d "${FILE}" ]; then
            # Включая директории.
            # COUNT=$((${COUNT:-0}+1));
            if [ ! -x "${FILE}" ]; then
                echo 1>&2 "${FILE}: no execute (or search) permission on file";
            else
                (discover "${FILE}");
            fi
        else
            COUNT=$((${COUNT:-0}+1));
        fi
    done
    
    if [ "${COUNT:-0}" -gt "${NUM}" ]; then
        echo "${DIR}" >> "${BIG_LIST}";
    else
        echo "${DIR}" >> "${SHORT_LIST}";
    fi
}

if [ -z "${*}" ]; then
    set "${PWD}";
fi

for DIR in "${@}"; do
    if [ ! -e "${DIR}" ]; then
        echo 1>&2 "${DIR}: No such file ir directory";
        continue;
    fi
    
    if [ ! -d "${DIR}" ]; then
        echo 1>&2 "${DIR} is a file, not a directory";
        continue;
    fi
    
    (discover "${DIR}");    
    
done

Тест.

#!/bin/sh

DIR="/tmp/d i r";
rm -rfv "${DIR}";

mkdir "${DIR}";
mkdir "${DIR}/dir";
touch "${DIR}/dir/.file";
touch "${DIR}/dir/file";

while [ ${N:-0} -le 10 ]; do
    N=$((${N}+1));
    touch "${DIR}/${N}";
done


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 19-Окт-14 14:44 
>Нам нужен отдельный счётчик для каждой директории, для этого мы используем subshell (В bash, можно использовать массив).

И "сбрасываем" значение счётчика для каждой директории.
> unset COUNT.

$ COUNT=0
$ echo $COUNT
$ a() { echo $COUNT; COUNT=$((${COUNT}+1)); }
$ a
$ echo $COUNT
$ (a)
$ echo $COUNT
$ a() { echo $COUNT; unset COUNT; COUNT=$((${COUNT}+1)); echo $COUNT; }
$ (a)
$ echo $COUNT


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 19-Окт-14 14:52 
Fix.

#!/bin/sh

NUM=10
BIG_LIST="${HOME}/BigList";
SHORT_LIST="${HOME}/ShortList";

discover() {
    unset COUNT;
    cd "${1}";
    
    # На случай, если по каким-либо причинам не удаётся перейти в диреторию.
    if [ $? -ne 0 ]; then
        echo 1>&2 "Cannot change working directory to ${1}";
        return 1;
    fi
    
    DIR="${PWD}";

    for FILE in .* *; do
        if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
            continue;
        fi

        if [ -d "${FILE}" ]; then
            # Включая директории.
            # COUNT=$((${COUNT:-0}+1));
            if [ ! -x "${FILE}" ]; then
                echo 1>&2 "${FILE}: no execute (or search) permission on file";
            else
                (discover "${FILE}");
            fi
        else
            COUNT=$((${COUNT:-0}+1));
        fi
    done
    
    if [ "${COUNT:-0}" -gt "${NUM}" ]; then
        echo "${DIR}" >> "${BIG_LIST}";
    else
        echo "${DIR}" >> "${SHORT_LIST}";
    fi
}

if [ -z "${*}" ]; then
    set "${PWD}";
fi

for DIR in "${@}"; do
    if [ ! -e "${DIR}" ]; then
        echo 1>&2 "${DIR}: No such file ir directory";
        continue;
    fi
    
    if [ ! -d "${DIR}" ]; then
        echo 1>&2 "${DIR} is a file, not a directory";
        continue;
    fi
    
    (discover "${DIR}");    
    
done


"Рекурсивный обход поддерикторий"
Отправлено CROSP , 19-Окт-14 15:31 
>[оверквотинг удален]
>  if [ ! -e "${DIR}" ]; then
>   echo 1>&2 "${DIR}: No such file ir directory";
>   continue;
>  fi
>  if [ ! -d "${DIR}" ]; then
>   echo 1>&2 "${DIR} is a file, not a directory";
>   continue;
>  fi
>  (discover "${DIR}");
> done

Спасибо ВАМ огромное !!!!! Буду разбираться со всем этим. Я просто никогда не мог подумать, что такую простую задачу на скриптовом языке так сложно(для меня) будет реализовать.
Раньше всегда думал что ассемблер это сложно. Спасибо Вам еще раз.


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 19-Окт-14 15:54 
Пожалуйста!

Проверьте поведение скрипта, если работает приемлемо — разбирайтесь.
Не забывайте о «трассировке».
$ set -x
$ sh -x script.sh 2>&1 | tee log

Так Вы увидите как работает скрипт.


"Рекурсивный обход поддерикторий"
Отправлено Аноним , 19-Окт-14 15:37 
a() { echo $COUNT; unset COUNT; COUNT=$((${COUNT:-0}+1)); echo $COUNT; }
или
a() { echo $COUNT; COUNT=0; COUNT=$((${COUNT}+1)); echo $COUNT; }

"Рекурсивный обход поддерикторий"
Отправлено Andrey Mitrofanov , 20-Окт-14 09:28 
> За /bin/sh и несоответствие ниженаписанному нужно бить, используя баш нужно в качестве
> интертпритатора его и указывать.

:) "Не за то отец сына бил, что с башизбами писал, а за то, что шибанг не ставил."


> И спасибо за светлое будущие.


"Рекурсивный обход поддерикторий"
Отправлено pavel_simple , 20-Окт-14 10:24 
>> За /bin/sh и несоответствие ниженаписанному нужно бить, используя баш нужно в качестве
>> интертпритатора его и указывать.
> :) "Не за то отец сына бил, что с башизбами писал, а
> за то, что шибанг не ставил."

не -- я тута не прав -- почему-то посчитал что $((${COUNT:-0}+1)); есть башизм, ну т.е. смотрю в книгу а вижу ${VAR:1:2}

>> И спасибо за светлое будущие.


"Рекурсивный обход поддерикторий"
Отправлено Andrey Mitrofanov , 20-Окт-14 12:17 
>${COUNT:-0}
> башизм, ну т.е. смотрю в книгу а вижу
>${VAR:1:2}

Это два _разных субститьюта (извините). Первый - подстановка, если переменная пуста, второй - substr()~~. И оба у меня сработали в bash --posix, а в dash - только первый. По стандарту POSIX я не ходок, но сие наводит Ж( некие сомнения и на плетень #!/bin/sh.


"Рекурсивный обход поддерикторий"
Отправлено pavel_simple , 20-Окт-14 16:31 
>>${COUNT:-0}
>> башизм, ну т.е. смотрю в книгу а вижу
>>${VAR:1:2}
> Это два _разных субститьюта (извините). Первый - подстановка, если переменная пуста, второй
> - substr()~~. И оба у меня сработали в bash --posix, а
> в dash - только первый. По стандарту POSIX я не ходок,
> но сие наводит Ж( некие сомнения и на плетень #!/bin/sh.

я собственно о том-же, первый посчитал за башизм, а здря.


"Рекурсивный обход поддерикторий"
Отправлено izyk , 20-Окт-14 13:20 
Дарю.

#!/bin/sh

file_cmd () {
$your_cmd "$1"
}

dir_parse () {
local From=${1%%/}
local Fn
for Fn in $(ls -A "$From"); do
  if [ -d "$From/$Fn" ]; then
    dir_parse "$From/$Fn"
  else
    file_cmd "$From/$Fn"
  fi;
done
}

dir_parse "$1"


"Рекурсивный обход поддерикторий"
Отправлено izyk , 20-Окт-14 13:51 
Sorry!
Прочитал только, заголовок.

"Рекурсивный обход поддерикторий"
Отправлено izyk , 20-Окт-14 14:22 
One more Sorry!

#!/bin/sh
set -eu
dir_cmd () {
if [ $# -le 10 ]
then
  echo less then 10 "$1"
else
  echo more then 10 "$1"
fi
}

dir_parse () {
local From=${1%%/}
local Fn
for Fn in $From/*; do
  if [ -d "$Fn" ]; then
    dir_cmd "$Fn" $(echo $Fn/\*)
    dir_parse "$Fn"
  fi;
done
}

dir_parse "$1"


"Рекурсивный обход поддерикторий"
Отправлено izyk , 20-Окт-14 14:46 
dir_parse () {
local From=${1%%/}
local Fn
for Fn in "$From"/*; do
  if [ -d "$Fn" ]; then
    dir_cmd "$Fn" "$Fn"/*
    dir_parse "$Fn"
  fi;
done
}

"Рекурсивный обход поддерикторий"
Отправлено Andrey Mitrofanov , 20-Окт-14 15:46 
> dir_cmd () {
> if [ $# -le 10 ]
> then
>   echo less then 10 "$1"

И пропатчить для имён с пробелами, двоеточиями, запятыми, и всякой всячиной в именах!

Не забыть [?про shellshock и] пр "\$\(rm\ -rf \~\)" именах _файлов.


"Рекурсивный обход поддерикторий"
Отправлено izyk , 20-Окт-14 20:00 

> И пропатчить для имён с пробелами, двоеточиями, запятыми, и всякой всячиной в
> именах!
> Не забыть [?про shellshock и] пр "\$\(rm\ -rf \~\)" именах _файлов.

#!/bin/sh
set -eu
dir_cmd () {
local Fn
for Fn in "$@"; do
  if [ ! -e "$Fn" -o "${Fn##*/}" = "." -o "${Fn##*/}" = ".." ]; then
    continue
  fi
  if [ $# -lt 10 ]
  then
    echo "$Fn" >> ShortList
  else
    echo "$Fn" >> BigList
  fi
done
}

dir_parse () {
local From="${1%%/}"
local Fn
for Fn in "$From"/* "$From"/.*; do
  if [ ! -e "$Fn" -o "${Fn##*/}" = "." -o "${Fn##*/}" = ".." ]; then
    continue
  fi
  if [ -d "$Fn" ]; then
    dir_cmd "$Fn"/* "$Fn"/.*
    dir_parse "$Fn"
  fi
done
}

dir_cmd "$1"/* "$1"/.*
dir_parse "$1"