2015-02-06 3 views
4

Я надеюсь, что это интересный вопрос .. Я хочу, чтобы найти каталог, который содержит все указанные файлы .. До сих пор, что я сделал не такПоиск каталогов, содержащих заданные файлы?

Найти несколько файлов в UNIX ...

find . -type f \(-name "*cache" -o -name "*xml" -o -name "*html" \) 

ссылка: http://alvinalexander.com/linux-unix/linux-find-multiple-filenames-patterns-command-example

Поиск только каталоги, содержащие данные файлы ...

find . -type f -name '*.pdf' |sed 's#\(.*\)/.*#\1#' |sort -u 

Ссылка: http://www.unix.com/unix-for-dummies-questions-and-answers/107488-find-files-display-only-directory-list-containing-those-files.html

Как я могу создать команду, которая даст мне каталог, который содержит все данные ... (Файлы должны быть в заданной директории, но не в подкаталоге .. и все файлы, указанные в список должен присутствовать)

Хотите найти тему каталогов WordPress

+0

Где список файлов, которые вы пытаетесь найти? – anubhava

+0

index.php style.css page.php single.php Основные основные файлы comment.php, необходимые для wordpress по теме wordpress. Моя цель - найти все темы Wordpress, присутствующие в данной Linux-системе. –

ответ

3

Вы можете использовать find так:

find -type d -exec sh -c '[ -f "$0"/index.php ] && [ -f "$0"/style.css ]' '{}' \; -print 

для поиска нескольких файлов, просто добавить их как && [ -f "$0"/other_file ]. Код возврата sh будет указывать, можно ли найти все файлы. Имя каталога будет напечатано только в том случае, если успешно завершил sh, т. Е. Когда все файлы были найдены.

Тестирование это:

$ mkdir dir1 
$ touch dir1/a 
$ mkdir dir2 
$ touch dir2/a 
$ touch dir2/b 
$ find -type d -exec sh -c '[ -f "$0"/a ] && [ -f "$0"/b ]' '{}' \; -print 
./dir2 

Здесь я создал две директории, dir1 и dir2. dir2 содержит оба файла, поэтому его название печатается.

Как gniourf_gniourf упомянул в комментариях (спасибо), для этого не нужно использовать sh. Вместо этого, вы можете сделать это:

find -type d -exec test -f '{}'/a -a -f '{}'/b \; -print 

[ и test делать то же самое. Этот подход использует -a вместо && для объединения нескольких отдельных тестов, что уменьшает количество выполняемых процессов.

В ответ на ваш комментарий, вы можете добавить все каталоги найденных в архив, как это:

find -type d -exec test -f '{}'/a -a -f '{}'/b \; -print0 | tar --null -T - -cf archive.tar.bz2 

Опция -print0 печатает имена каждого из каталогов, разделенных нулевым байтом. Это полезно, поскольку оно предотвращает проблемы с файлами, содержащими пробелы в их именах. Имена читаются tar и добавляются в архив, сжатый в bzip. Обратите внимание, что некоторые версии find не поддерживают опцию -print0. Если ваша версия не поддерживает его, вы можете использовать -print (и удалить опцию --null до tar), в зависимости от ваших имен каталогов.

+0

Как сжать все каталоги, которые мы получаем в качестве вывода указанной команды ??? Я хочу добавить сразу все каталоги в архив ... –

+0

@vivek Я отредактировал свой ответ –

+0

Невозможно распаковать архив, получив ошибку, так как archive.tar.bz2 не похож на файл tar.
bzip2 -cd archive.tar.bz2 | tar xvf -
bzip2 -d archive.tar.bz2
tar xvjf archive.tar.bz2
tar jfx archive.tar.bz2, а также как запустить команду через функцию PHP exec()? Мне нужно хранить каталоги в массиве в PHP. Спасибо в Advance :) –

1

Вы можете использовать этот скрипт:

#!/bin/bash 

# list of files to be found 
arr=(index.php style.css page.php single.php comment.php) 
# length of the array 
len="${#arr[@]}" 

# cd to top level themes directory 
cd themes 

# search for listed files in all the subdirectories from current path 
while IFS= read -d '' -r dir; do 
    [[ $(ls "${arr[@]/#/$dir/}" 2>/dev/null | wc -l) -eq $len ]] && echo "$dir" 
done < <(find . -type d -print0) 
+0

Он отлично работает и дает ожидаемый результат. Спасибо за ваше время, сэр. Он отлично работает, когда я запускаю его через командную строку, но он дает ошибку, как «синтаксическая ошибка около неожиданного токена' <'в строке номер 11. Остальное все в порядке. Спасибо, сэр ... –

+0

Оба ответа верны, но я не может их принять, он просто держит между ними связь. –

+0

Да, вы не можете отметить оба ответа как принятые. Будет отмечен только тот, который лучше всего подходит для вас. – anubhava

Смежные вопросы