bash-скриптинг: параллель для циклов - PullRequest
3 голосов
/ 07 ноября 2011

Я пишу сценарий bash для циклического прохождения 2 одинаковых деревьев каталогов, чтобы выполнить diff для соответствующих файлов. Мне просто нужно знать, каков правильный синтаксис для установки 2 циклов, которые будут работать параллельно. Я также хотел бы рекурсивно перебирать каталоги, поэтому, если для этого есть дополнительный шаг, можете ли вы упомянуть об этом?

#!/bin/bash
FILES1=/path/to/one
FILES2=/path/to/two
for f1 in $FILES1; f2 in $FILES2
do
  echo "Processing $f1 $f2 file..."
done

Ответы [ 3 ]

3 голосов
/ 07 ноября 2011

Нет никакой гарантии, что файлы будут в одинаковом порядке в двух каталогах.

Сделай так:

FILES1=/path/to/one
FILES2=/path/to/two
for f1 in $FILES1/*
do
  f2=$FILES2/`basename f1`
  # ...
done

А если вам нужно сделать это рекурсивно:

cd $FILES1
for f1 in `find`; do
  f2=$FILES2/$f1
  # ...
done
3 голосов
/ 08 ноября 2011

diff уже имеет встроенную функциональность для рекурсивной работы с каталогами.Вы можете запустить diff -Naur /path/to/one /path/to/two.

  • -N покажет diff для новых файлов, вместо того, чтобы просто сказать, что он существует во втором пути
  • -a рассматривает все файлы кактекст, так что вам может понадобиться, а может и не понадобиться.
  • -u использует общий унифицированный формат diff
  • -r является важным, в данном случае, рекурсивным флагом
0 голосов
/ 07 ноября 2011

Самое близкое, что вы можете получить, это вложить циклы for, то есть

   for f in $FILES1 ; do
      for f2 in $FILES2 ; do
         if [ ${f##*/} = ${f2##*/} ]; then
             diff $f $f2
             break
         fi
      done
  done

для итерации по рекурсивным dir, вы можете положиться на find, чтобы вернуть список файлов для обработки

 PATH1=/path/to/one
 PATH2=/path/to/two

 for f in $(find $PATH1 -print ) ; do
    for f2 in $(find $PATH2 -print ) ; do
       if [ ${f##*/} = ${f2##*/} ]; then
           diff $f $f2
           break
       fi
    done
done

Извините, у меня нет способа проверить это сейчас, ${f##*/} может быть не совсем правильным.Намерение состоит в том, чтобы создать только базовое имя файла (я думаю, вы могли бы также использовать его, $(basename $f ) за счет 2 процессов для каждого.

Оба эти процесса являются очень дорогими, проверяя множествонесовпадающие пары имен файлов. Разрыв внутри loop2 немного помогает.

Альтернативное решение - использовать один путь для создания списка драйверов, а затем использовать предоставленные имена для генерации альтернативных относительных путей, например

for f in $FILES1 ; do
   f2=../two/$f{##*/}
   if [ -f ${f2} ] ; the
       diff $f $f2
   else
       printf "no alternate file found in ../two for f=${f}"
   fi
done

Если необходимо, вы можете продублировать этот цикл и поменять местами f2 и f, чтобы проверить «другую сторону» вашей системы.

Надеюсь, это поможет.

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