2015-03-04 2 views
0

Допустим /tmp/test1 подкаталоги, /test2, /test3 и так далее, и каждый имеет несколько файлов внутри.Найти имя поддиректории и технологических файлов в каждой

я должен запустить while петлю или for петлю, чтобы найти имя каталогов (в этом случае /test1, /test2, ...) и запустить команду, которая обрабатывает все файлы внутри каждого каталога.

Так, например, я должен получить имена каталогов под /tmp, которые будут test1, test2, ... Для каждого подкаталога, я должен обрабатывать файлы внутри него.

Как это сделать?


Разъяснение:

Это команда, которую я хочу запустить:

find /PROD/140725_D0/ -name "*.json" -exec /tmp/test.py {} \; 

где 140725_D0 является примером один подкаталога процесса - есть кратные, с разными именами ,

Итак, используя цикл for или while, я хочу найти все подкаталоги и выполнить команду по файлам в каждом.

Петля for или while должна итеративно заменить твердое имя 140725_D0 в команде поиска выше.

+0

Я убрал ваш вопрос; если вы сейчас посмотрите на источник вопроса, вы должны иметь возможность определить, как форматируется код. – mklement0

ответ

1

Вы должны быть в состоянии сделать с однойfind команды с встроенной командой оболочки:

find /PROD -type d -execdir sh -c 'for f in *.json; do /tmp/test.py "$f"; done' \; 

Примечание: -execdir не POSIX-совместимые, но BSD (OSX) и GNU (Linux) версии find поддерживают его; см. ниже для альтернативы POSIX.

  • подход должен позволить find матчу каталогов, а затем, в каждой согласованной директории, выполнить оболочку с петлей файла обработка (sh -c '<shellCmd>').
  • Если не все подкаталоги гарантированно иметь *.json файлы, изменять команду оболочки для for f in *.json; do [ -f "$f" ] && /tmp/test.py "$f"; done

Update: еще два соображения; Кончик шляпу kenorb's answer:

  • По умолчанию find обрабатывает все поддерево каталога ввода. Для того, чтобы ограничить соответствия для непосредственных подкаталогов, используйте -maxdepth 1[1]:

    find /PROD -maxdepth 1 -type d ... 
    
  • Как уже говорилось, -execdir - который запускает команду, переданные ему в каталоге обрабатываемой в данный момент - это не POSIX совместимый; Вы можете обойти эту проблему с помощью -exec, а и пути включения cd команды с путем каталога под рукой ({}) в команде оболочки:

    find /PROD -type d -exec sh -c 'cd "{}" && for f in *.json; do /tmp/test.py "$f"; done' \; 
    

[1] Строго говоря , вы можете поместить опцию -maxdepthв любом месте после входных путей файла в командной строке find - в качестве опции , он не позиционный. Однако GNU find будет выдавать предупреждение, если вы поместите его передтесты (например, -type) иДействия (например, -exec).

+0

Где я могу добавить maxdepth? он пришел до -exec или после? – Young

+0

@Young: поместите его перед '-type d' (см. Мое обновление). – mklement0

0

Вы можете сделать функцию подоболочку это с помощью BASH как так

for i in /tmp/test*; do 
    # don't do anything if there's no /test directory in /tmp 
    [ "$i" != "/tmp/test*" ] || continue 

    for j in $i/*.json; do 
    # don't do anything if there's nothing to run 
    [ "$j" != "$i/*.json" ] || continue 

    (cd $i && ./file_to_run) 
    done 
done 

Когда вы заключаете команду в ( и ) он начинает подоболочку для запуска команды. Подселл похож на запуск другого экземпляра bash, за исключением того, что он немного более оптимален.

+0

Я хотел сказать, что .. позволяет сказать, что вы не знаете, содержит ли tmp/test * .. вам нужно проверить каталог, чтобы увидеть, что там есть, и запустить все каталоги. также вы не знаете, какие файлы там. Скажем, в каждом подкаталоге содержится несколько json-файлов .. вам нужно запустить все json – Young

+0

Так что я думаю, что лучше использовать цикл while, чтобы я мог запускать файлы если есть какие-то вспомогательные каталоги .. и если есть, найдите это имя и запустите эти подкаталоги – Young

+0

@Young Смотрите мои правки – randomusername

1

Попробуйте следующее использование find:

find . -type d -exec sh -c 'cd "{}" && echo Do some stuff for {}, files are: $(ls *.*)' ';' 

Используйте -maxdepth, если вы хотите, чтобы ограничить уровни каталогов.

+1

Kudos для' -maxdepth' и альтернативы '-execdir', совместимой с POSIX (' -exec' + 'cd" {} "' команда оболочки). – mklement0

0

Вы также можете просто попросить оболочку развернуть каталоги/файлы, которые вам нужны, например. с помощью команды xargs:

echo /PROD/*/*.json | xargs -n 1 /tmp/test.py 

или даже используя исходный find команду:

find /PROD/* -name "*.json" -exec /tmp/test.py {} \; 

Обе команды будет обрабатывать все файлы, содержащиеся в формате JSON в любой подкаталог /PROD.

0

Другое решение - немного изменить код Python внутри вашего скрипта, чтобы принимать и обрабатывать несколько файлов. Например, если сценарий содержит что-то вроде:

def process(fname): 
    print 'Processing file', fname 

if __name__ == '__main__': 
    import sys 
    process(sys.argv[1]) 

вы могли бы заменить последнюю строку с:

for fname in sys.argv[1:]: 
     process(fname) 

После этой простой модификации, вы можете позвонить сценарий таким образом:

/tmp/test.py /PROD/*/*.json 

и обработать все необходимые файлы JSON.