Рекурсивно читать папки и выполнять команду для каждого из них
Я пытаюсь перезаписать папки и запустить на них команды, используя 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).