Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > *NIX системы: Общие вопросы > Рекурсивный поиск по всем поддиректориям


Автор: Kosya4ok 21.11.2007, 20:22
Всем доброе время суток.
Задача следующая: требуется выполнить поиск по всем директория данной директории и запустить в них команду которая показывает путь к директории в которой ты находишься в данный момент.

На ум приходит следующее:

#!/bin/sh
for $i in *
do
  if test -d $i
    path=`pwd`
    cd $path/$i/
    echo `cd $path/$i/`
    ./$0
done

Но блин, скриптец заходит только по первым директориям и не возвращается обратно. У кого есть какие идеи? Буду рад услышать.  

Автор: nickless 21.11.2007, 20:46
Цитата(Kosya4ok @  21.11.2007,  18:22 Найти цитируемый пост)
выполнить поиск по всем директория данной директории и запустить в них команду которая показывает путь к директории в которой ты находишься в данный момент.

Долго читал это предложение, но так и не понял какие директории нужно когда выводить.

Код
find * -type d

Оно? Если нет, объясните с примером что нужно сделать.

Автор: MAKCim 21.11.2007, 22:42


Добавлено через 9 минут и 19 секунд
Код

#!/bin/bash

function directory() {
for i in $1/*
do
    [ -d $i ] && {
        local STRING=$1/$i
        echo $STRING
        directory $STRING
    }
done
}

Автор: Kosya4ok 21.11.2007, 22:53
Супер! Я када потестил твой код просто отпал!Ты понял всё правильно, но есть нюанс! 

Вот если я напишу так:

Код

find * -type d
echo "I am here!"


То команда сперва пройдёт по всем директориям и вложенным директориям и тока затем выведет на экран I am here!. А мне надо чтобы заходя в каждую директорию запускалась команда echo "I am here!".

Автор: nickless 21.11.2007, 23:17
Код
find * -type d -printf 'I am here: %p\n'

Или делай рекурсивно функцией, как написал MAKCim

Если нужно именно чтоб запускалась комманда, используй -exec вместо -printf, как это сделать читай в man find.

Автор: Kosya4ok 21.11.2007, 23:48
Потестил код MAKCim.

Код

#!/bin/sh
function directory()
{
for i in $1/*
do
  if test -d "$i" &&
  {
     local STRING=$1/$i
     echo $STRING
     directory $STRING
   }
done
}


Выдаёт ошибку ./alex_8[2]: 0403-057 Syntax error at line 2 : `(' is not expected.
alex_8 - это имя моего скрипта. 
Походу что то не очень гладко. Да и просьба объяснить $1/*, if test -d "$i" &&, почему под if всё взято в фигурные скобки?, что означает объвление local STRING, а выражение directory $STRING как мы такое можем делать если у нас функция не принимает никаких значений. Я просто не работал в шеле с функциями поэтому можно немного дать пояснений. Спасибо. 

Автор: nickless 22.11.2007, 00:00
Цитата(MAKCim @  21.11.2007,  20:42 Найти цитируемый пост)
#!/bin/bash

Цитата(Kosya4ok @  21.11.2007,  21:48 Найти цитируемый пост)
#!/bin/sh

У него не зря там /bin/bash написанo smile , стандартный sh умеет гораздо меньше чем bash
Фигурные скобки это блок комманд, local объявляет переменную, а функции имеют несколько другой синтакс чем в обычных языках программирования.
Советую почитать http://tldp.org/LDP/abs/html/index.html, где-то тут на форуме я видел ссылку на русский перевод.

Автор: Kosya4ok 22.11.2007, 00:05
А после кода 

Код

#!/bin/sh
find * -type d -printf 'I am here!: %p\n'


find: 0652-017 -printf is not a valid option.

Попробывал сделать так, так как в манах был описана опция именно print 
Код

#!/bin/sh
find * -type d -print 'I am here!: %p\n'


Вывалилось find: 0652-009 There is a missing conjunction

Окей я тогда немного уточню задачу. Мне не требуется чтобы именно в каждой директории делаль вывод пути, а именно чтобы в каждой директории запускалась определённая неважно какая команда. 
Например, у меня есть скрипт который убирает не нужные файлы из системы. Так вот я захожу в 1 директорию его там запускаю, во 2 и т.д. И для этой цели как пример надо использовать обход по всем вложенным папкам.

Автор: nickless 22.11.2007, 00:24
Цитата(Kosya4ok @  21.11.2007,  22:05 Найти цитируемый пост)
find: 0652-017 -printf is not a valid option.

Что это за версия find где нет -printf?

Посмотри есть ли там -execdir или -exec, это вроде есть в POSIX. Если нет, есть еще программа xargs ею можно передавать вывод find другому скрипту, вроде
Код

find * -type d | xargs -n1 ls -lad

Автор: Kosya4ok 22.11.2007, 00:33
При замене #!/bin/sh на !#/bin/bash выдаёт ksh: ./alex_8_MAKCim:  not found.

Еси уже на то пошло то function объвлена тока в ksh http://bama.ua.edu/cgi-bin/man-cgi?00+00 

А зачем переменную объвялть через local?Мона ж ипросто объявить STRING. Так а $1/*, if test -d "$i" &&.
Так а зачем посе if ставить фигурные скобки еси мона после каждого блока ставить точку с запятой?

P.S.  И еси мона сцылку на русскуий перевод Advanced Bash-Scripting Guide.

Добавлено через 11 минут и 3 секунды
Код

#!/bin/sh
find * -type d | xargs -n1 ls -lad

Работает замечательно, но вот тока куда мне теперь вставить свою команду (см. пример выше)?

P.S. Да и еси можно пояснения к коду. Ну вот например find * -type d выводит список всех поддиректорий, а дальше перенаправляется в | xargs -n1 ls -lad и что происходит? Сенкс.

При
Код

#!/bin/sh
find * -type d -exec 'I am here: %p\n'


Выдаёт: find: 0652-018 An expression term lacks a required parameter.

А при
Код

#!/bin/sh
find * -type d -execdir 'I am here: %p\n'

ВЫдаёт: find: 0652-017 -execdir is not a valid option.

Может это я как то не правильно использую опции в find?

Автор: Бонифаций 22.11.2007, 00:54
find . -type d -exec echo "I am in {}" \;

Автор: MAKCim 22.11.2007, 01:01
Цитата(Kosya4ok @  22.11.2007,  00:05 Найти цитируемый пост)
Мне не требуется чтобы именно в каждой директории делаль вывод пути, а именно чтобы в каждой директории запускалась определённая неважно какая команда. 

Код

#!/bin/bash
function directory() {
    $2 $1
    for i in $1/*
    do
        [ -d $i ] && { directory $1/$i $2 }
    done
}

directory / ls


Добавлено через 2 минуты и 11 секунд
Цитата(Kosya4ok @  22.11.2007,  00:33 Найти цитируемый пост)
А зачем переменную объвялть через local?Мона ж ипросто объявить STRING

можно и глобальные данные в ЯВУ использовать  smile 
но это ж не значит, что нужно

Автор: Kosya4ok 22.11.2007, 01:11
Бонифаций а вы сами тестировали ваш код?

Код

#!/bin/sh
find . -type d -exec echo "I am in {}" \;


Выводит: 

I am in {}
I am in {}
I am in {}
I am in {}
I am in {}

Ровно стока раз сколько у меня и вложенных директорий. Any suggestion? smile

Добавлено через 8 минут и 16 секунд
MAKCim а как твой скрипт юзать?
Набирать типа ./alex_8_MAKCim_1 команда_которую_я_хочу_выполнить?

P.S. Если да, то ./alex_8_MAKCim_1 ls -l
Выдаёт: ksh: ./alex_8_MAKCim_1:  not found.

Я так понимаю мне надо поменять интерпретаор с ksh на bash? А как это сделать если у меня нет ажминских прав?

Автор: nickless 22.11.2007, 01:35
Цитата(Kosya4ok @  21.11.2007,  22:33 Найти цитируемый пост)
При замене #!/bin/sh на !#/bin/bash выдаёт ksh: ./alex_8_MAKCim:  not found.

Расскажи ка для начала что у тебя за система и шелл.
*nix-ы могут сильно отличатся версиями комманд, у большинства стоит linux, там у всех стандартных комманд есть куча GNU-расширений, а у тебя похоже что-то другое.

Цитата(Kosya4ok @  21.11.2007,  22:33 Найти цитируемый пост)
P.S.  И еси мона сцылку на русскуий перевод Advanced Bash-Scripting Guide.

Судя по ошибкам в твоей системе не установлен bash, по этому вряд ли bash scripting guide сильно поможет, надо тебе смотреть документацию к ksh (там синтакс немного отличается).

Цитата(Kosya4ok @  21.11.2007,  22:33 Найти цитируемый пост)
а дальше перенаправляется в | xargs -n1 ls -lad и что происходит?

А дальше перенаправляется в xargs (man xargs), а остальное это параметр к нему и комманда ls с параметром -lad (man ls), в данном случае xargs вызавает ls с параметром -lad для каждой строки.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)