рекурсивный diff очень медленный - проверка содержимого каталогов - PullRequest
5 голосов
/ 17 марта 2011

Эй, ребята, я запускаю diff по двум каталогам, рекурсивно, с несколькими вариантами. каталоги несколько большие, однако я пытаюсь просто увидеть различия в содержимом папок, а не между файлами, используя опцию -q (я использую это право?)

Я также пробовал rsync всухую, что, кажется, занимает столько же времени. вывод идет через седь, я пробовал без, это, кажется, ничего не влияет. я также игнорирую скрытые файлы. я думаю, что я могу неправильно использовать diff -q, чтобы просто сравнить содержимое двух каталогов.

я использовал блок кода из другого совета, как долго сравнивалось ОДНО из этих каталогов (1 каталог, 14 подкаталогов), и это заняло 88 минут. однако каждый файл представлял собой 30-минутное телешоу, так что если diff сравнивает эти файлы, это имеет смысл, но я подумал, что -q приведет к тому, что этого не произойдет?

также, один каталог монтируется через AFP, один - внешний диск, подключенный через FireWire. это не имеет значения, потому что я скопировал обе директории локально и разность заняла одинаковое количество времени. У меня действительно есть решение этой проблемы - я запускаю ls -1 по обоим каталогам и проверяю вывод - но почему diff занимает так много времени для запуска?

вот код; какие-либо предложения?

#!/bin/bash

before="$(date +%s)"

diff -r -x '.*' /Volumes/directory1/ /Volumes/directory2/ | sed 's/^.\{24\}//g' > /Volumes/stuff.txt
diff -r -x '.*' /Volumes/directory3/ /Volumes/directory4/ | sed 's/^.\{24\}//g' > /Volumes/stuff.txt
diff -r -x '.*' /Volumes/directory5/ /Volumes/directory6/ | sed 's/^.\{24\}//g' > /Volumes/stuff.txt
diff -r -x '.*' /Volumes/directory7/ /Volumes/directory8/ | sed 's/^.\{24\}//g' > /Volumes/stuff.txt
diff -r -x '.*' /Volumes/directory9/ /Volumes/directory10/ | sed 's/^.\{24\}//g' > /Volumes/stuff.txt
diff -r -x '.*' /Volumes/directory11/ /Volumes/directory12/ | sed 's/^.\{24\}//g' > /Volumes/stuff.txt

after="$(date +%s)"
elapsed_seconds="$(expr $after - $before)"
echo Elapsed time for code block: $elapsed_seconds

1 Ответ

11 голосов
/ 17 марта 2011

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

Если все, что вас волнует, это различия в именах файлов и вы не хотите проверять содержимое файлов, попробуйте что-то вроде:

diff <(find /Volumes/directory1/ -printf '%P\n') \
     <(find /Volumes/directory2/ -printf '%P\n')

Предполагается, что вы нашли GNU с действием -printf. Если вы этого не сделаете, используйте магию подоболочки за комментарий Гордона:

diff <(cd /Volumes/directory1; find .) \
     <(cd /Volumes/directory2; find .)
...