The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Рекурсивный обход поддерикторий"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Shell скрипты)
Изначальное сообщение [ Отслеживать ]

"Рекурсивный обход поддерикторий"  +1 +/
Сообщение от CROSP email(ok) on 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
Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Рекурсивный обход поддерикторий"  +/
Сообщение от CROSP (ok) on 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

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

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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
}


Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

5. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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

Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "Рекурсивный обход поддерикторий"  +/
Сообщение от тень_pavel_simple on 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 и несоответствие ниженаписанному нужно бить, используя баш нужно в качестве интертпритатора его и указывать.

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

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

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

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

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

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "Рекурсивный обход поддерикторий"  +/
Сообщение от CROSP (ok) on 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

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

9. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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

Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

10. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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

Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

11. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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

Ответить | Правка | ^ к родителю #10 | Наверх | Cообщить модератору

12. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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

Ответить | Правка | ^ к родителю #11 | Наверх | Cообщить модератору

13. "Рекурсивный обход поддерикторий"  +/
Сообщение от CROSP email(ok) on 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

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

Ответить | Правка | ^ к родителю #12 | Наверх | Cообщить модератору

15. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 19-Окт-14, 15:54 
Пожалуйста!

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

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

Ответить | Правка | ^ к родителю #13 | Наверх | Cообщить модератору

14. "Рекурсивный обход поддерикторий"  +/
Сообщение от Аноним (??) on 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; }
Ответить | Правка | ^ к родителю #11 | Наверх | Cообщить модератору

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

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


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

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

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

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

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

Ответить | Правка | ^ к родителю #16 | Наверх | Cообщить модератору

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

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

Ответить | Правка | ^ к родителю #17 | Наверх | Cообщить модератору

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

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

Ответить | Правка | ^ к родителю #18 | Наверх | Cообщить модератору

19. "Рекурсивный обход поддерикторий"  +/
Сообщение от izyk email(ok) on 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"

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

20. "Рекурсивный обход поддерикторий"  +/
Сообщение от izyk email(ok) on 20-Окт-14, 13:51 
Sorry!
Прочитал только, заголовок.
Ответить | Правка | ^ к родителю #19 | Наверх | Cообщить модератору

21. "Рекурсивный обход поддерикторий"  +/
Сообщение от izyk email(ok) on 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"

Ответить | Правка | ^ к родителю #19 | Наверх | Cообщить модератору

22. "Рекурсивный обход поддерикторий"  +/
Сообщение от izyk email(ok) on 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
}
Ответить | Правка | ^ к родителю #21 | Наверх | Cообщить модератору

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

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

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

Ответить | Правка | ^ к родителю #21 | Наверх | Cообщить модератору

25. "Рекурсивный обход поддерикторий"  +/
Сообщение от izyk email(ok) on 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"

Ответить | Правка | ^ к родителю #23 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру