Рекурсивно читает папки и выполняет команды на каждой из них - PullRequest
19 голосов
/ 26 августа 2009

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

Ответы [ 7 ]

46 голосов
/ 26 августа 2009

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

Эта команда может получать множество параметров, например 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'
...


Кто-то скажет «это не снаряд» ... Но зачем изобретать велосипед?
(И, в некотором смысле, это оболочка ^^)


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

9 голосов
/ 27 октября 2015

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

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

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

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

7 голосов
/ 27 августа 2009

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

function RecurseDirs
{
    oldIFS=$IFS
    IFS=$'\n'
    for f in "$@"
    do
    -----your activity here-----
        if [[ -d "${f}" ]]; then
            cd "${f}"
            RecurseDirs $(ls -1 ".")
            cd ..
        fi
    done
    IFS=$oldIFS
}
4 голосов
/ 23 января 2013

В некоторых базовых оболочках отсутствуют команды типа «найти», а некоторые из них не поддерживают рекурсивность В этом случае вы можете использовать этот скрипт для запуска желаемой команды во всех подкаталогах дерева:

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>

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

./recurse.sh "chown 0:0 *"
2 голосов
/ 26 августа 2009

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

find -type d -exec scriptname.sh \{\} \;
1 голос
/ 26 августа 2009

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

0 голосов
/ 26 августа 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...