Рекурсивно читать папки и выполнять команду для каждого из них

Я пытаюсь перезаписать папки и запустить на них команды, используя bash script. Любые предложения?

Ответы

Ответ 1

Если вы хотите записаться в каталоги, выполнив команду для каждого найденного в них файла, я бы использовал команду find вместо того, чтобы писать что-либо с помощью shell-script, я думаю.

Эта команда может получать множество параметров, например type, для фильтрации возвращаемых типов файлов или exec для выполнения команды для каждого результата.


Например, чтобы найти каталоги, которые находятся под той, в которой я сейчас:

find . -type d -exec echo "Hello, '{}'" \;

Который доставит мне что-то вроде:

Hello, '.'
Hello, './.libs'
Hello, './include'
Hello, './autom4te.cache'
Hello, './build'
Hello, './modules'


То же самое, чтобы найти файлы в текущем каталоге:

find . -type f -exec echo "Hello, '{}'" \;

который получит мне что-то вроде этого:

Hello, './config.guess'
Hello, './config.sub'
Hello, './.libs/memcache_session.o'
Hello, './.libs/memcache_standard_hash.o'
Hello, './.libs/memcache_consistent_hash.o'
Hello, './.libs/memcache.so'
Hello, './.libs/memcache.lai'
Hello, './.libs/memcache.o'
Hello, './.libs/memcache_queue.o'
Hello, './install-sh'
Hello, './config.h.in'
Hello, './php_memcache.h'
...


Некоторые говорили бы "это не раковина"... Но зачем же изобретать колесо?
(И, в некотором смысле, это shell ^^)


Для получения дополнительной информации вы можете посмотреть:

Ответ 2

Что-то вроде этого должно достичь вашей цели:

function RecurseDirs
{
    oldIFS=$IFS
    IFS=$'\n'
    for f in "[email protected]"
    do
    -----your activity here-----
        if [[ -d "${f}" ]]; then
            cd "${f}"
            RecurseDirs $(ls -1 ".")
            cd ..
        fi
    done
    IFS=$oldIFS
}

Ответ 3

Bash 4.0 ввел параметр globstar, поэтому конструкция вроде:

for f in mydir/**/*
do
  # operations here
done

... будет действовать рекурсивно на любые земли в $f. Включите это с помощью "shopt-globstar", иначе ** будет рассматриваться как единственное *.

Нашел этот драгоценный камень сегодня в http://www.linuxjournal.com/content/globstar-new-bash-globbing-option, после того как он вдохновлен конструкцией zsh (которую я включил по умолчанию).

Ответ 4

Извините, я не понимаю, о чем вы спрашиваете. Лучшее, что я могу догадаться с вашим вопросом:

find -type d -exec scriptname.sh \{\} \;

Ответ 5

Некоторые базовые оболочки пропускают команды вроде "find", а некоторые из их команд не поддерживают рекурсию. В этом случае вы можете использовать этот script для запуска нужной команды во всех поддиректорах дерева:

CDIR=$(pwd)
for i in $(ls -R | grep :); do
    DIR=${i%:}                    # Strip ':'
    cd $DIR
    $1                            # Your command
    cd $CDIR
done

Если вы назовете вышеуказанный "recurse.sh", используйте:

./recurse.sh <command>

Пример (измените владельца/группу на "root" всех файлов в дереве):

./recurse.sh "chown 0:0 *"

Ответ 6

Посмотрите на команду find и проверьте переключатели -type (используйте d для указания каталога) и -exec (чтобы указать команду для выполнения).

Ответ 7

Для большинства рекурсивных файловых операций вы хотите использовать find, как объясняют другие ответы.

Существует пример рекурсивного bash script, включенного в пакет bash-doc. Если вы установили эти примеры, это будет в /usr/share/doc/bash/examples/functions/recurse (на Debian).