Bash: как пройти через структуру каталогов и выполнить команды? - PullRequest
8 голосов
/ 16 июня 2009

Я разбил большой текстовый файл на несколько наборов меньших для тестирования производительности, которое я делаю. Есть несколько каталогов, подобных этому:

/home/brianly/output-02 (contains 2 files myfile.chunk.00 and myfile.chunk.01)
/home/brianly/output-04 (contains 4 files...)
/home/brianly/output-06 (contains 6 files...)

Важно отметить, что в каждом каталоге растет количество файлов. Что мне нужно сделать, это запустить исполняемый файл для каждого из текстовых файлов в выходных каталогах. Команда выглядит примерно так с одним файлом:

./myexecutable -i /home/brianly/output-02/myfile.chunk.00 -o /home/brianly/output-02/myfile.chunk.00.processed

Здесь параметр -i является входным файлом, а параметр -o - местом вывода.

В C # я перебирал каталоги, получал список файлов в каждой папке, а затем перебирал их для запуска командной строки. Как мне пройти через структуру каталогов с помощью bash и выполнить команду с правильными параметрами, основанными на расположении и файлах в этом расположении?

Ответы [ 6 ]

8 голосов
/ 17 июня 2009

Для такого рода вещей я всегда использую find вместе с xargs :

$ find output-* -name "*.chunk.??" | xargs -I{} ./myexecutable -i {} -o {}.processed

Теперь, поскольку ваш сценарий обрабатывает только один файл за раз, использование -exec (или -execdir ) напрямую с find , как уже предлагалось, столь же эффективен, но я привык использовать xargs , поскольку это обычно намного эффективнее, когда передается команда, работающая с несколькими аргументами одновременно. Таким образом, это очень полезный инструмент для хранения в своем поясе, поэтому я подумал, что об этом следует упомянуть.

7 голосов
/ 16 июня 2009

Что-то вроде:

for x in `find /home/brianonly -type f`
do
./yourexecutable -i $x -o $x.processed
done
2 голосов
/ 16 июня 2009

Как предлагали другие, используйте find(1):

# Find all files named 'myfile.chunk.*' but NOT named 'myfile.chunk.*.processed'
# under the directory tree rooted at base-directory, and execute a command on
# them:
find base-directory -name 'output.*' '!' -name 'output.*.processed' -exec ./myexecutable -i '{}' -o '{}'.processed ';'
1 голос
/ 17 июня 2009

Исходя из предоставленной информации, звучит так, будто это будет совершенно прямой перевод вашей идеи C #.

for i in /home/brianly/output-*; do
    for j in "$i/"*.[0-9][0-9]; do
        ./myexecutable -i "$j" -o "$j.processed"
    done
done
0 голосов
/ 16 июня 2009

Используйте find и exec. Посмотрите на следующие

http://tldp.org/LDP/abs/html/moreadv.html

0 голосов
/ 16 июня 2009

Для этого и нужна команда find.

http://linux.die.net/man/1/find

...