Вопрос или проблема
Как я могу сравнить подсистемы в двух директориях до определенной глубины? Команда diff
не имеет опции для указания глубины, а опция -r
приводит к сравнению всех файлов, что я хотел бы избежать.
В основном, я хотел бы сделать следующее:
cd dir1
for d in */*/*; do test -d dir2/$d || echo $d; done
но более элегантно с помощью одной команды и без цикла.
Когда diff
получает две директории в качестве операндов, он сравнит файлы, присутствующие в двух директориях, без рекурсии. Это стандартное поведение.
Чтобы сравнить две структуры директорий до определенной глубины, не используя какую-либо рекурсивную логику diff
(которая не может быть ограничена по глубине), вы можете использовать find
в одной из структур, и для каждой найденной директории сравнивать её с соответствующей директорией в другой структуре. Вы можете ограничить глубину, на которую find
спускается в структуру.
find dir-a -type d -exec sh -c 'diff "$1" "dir-b/${1#dir-a}"' sh {} \;
dir-a будет вызван короткий встроенный скрипт. Скрипт получит относительное имя пути найденной директории (начиная с dir-a
) в качестве единственного аргумента в $1
. Он вызывает diff
для найденной директории и для того же пути в dir-b
. Путь dir-b
формируется заменой dir-a
в начале найденного имени пути на dir-b
.
Встроенный скрипт оболочки предполагает, что данный путь существует в dir-b
. Если это не так, diff
выдаст вам сообщение об ошибке “Нет такого файла или директории”.
Если вы хотите ограничить глубину, до которой проводится это сравнение, используйте -maxdepth N
(для некоторой глубины N
) перед -type d
, если ваш find
поддерживает это. Вы можете достичь того же эффекта с помощью -path '*/*/*' -prune
(приблизительно то же самое, что и -maxdepth 2
, но с использованием стандартных предикатов).
Ответ или решение
Как ограничить команду "diff -r" до определенной глубины
Команда diff
в стандартном виде не предоставляет функции для ограничения глубины рекурсивного сравнения каталогов с использованием флага -r
. Это может быть проблемой, если вам требуется сравнить каталоги до определенной глубины. Тем не менее, с помощью утилиты find
можно достичь этой цели более элегантным способом, избегая использования циклов.
Использование команды find
для сравнения каталогов
Для того чтобы выполнить сравнение подкаталогов в двух различных директориях до определенной глубины, можно использовать команду find
вместе с diff
. Вот как это можно сделать:
- Определите каталоги для сравнения. Пусть у вас есть два каталога:
dir-a
иdir-b
. - Используйте команду
find
для поиска директорий. Вам нужно найти все подкаталоги вdir-a
до определенной глубины. - Сравните найденные директории с директориями в
dir-b
. При помощи встроенной команды оболочки вы сможете сравнить соответствующие директории.
Пример команды
Вот пример команды, которая позволяет это сделать. В данном случае мы будем ограничивать глубину до 2:
find dir-a -maxdepth 2 -type d -exec sh -c 'diff "$1" "dir-b/${1#dir-a/}"' sh {} \;
Объяснение команды:
find dir-a
— ищет в каталогеdir-a
.-maxdepth 2
— ограничивает поиск до глубины 2.-type d
— ищет только каталоги.-exec sh -c '...' sh {}
— выполняет заданную команду для каждого найденного каталога.
Внутри скрипта:
diff "$1" "dir-b/${1#dir-a/}"
— команда сравнения, где$1
— это путь к текущему каталогу вdir-a
, аdir-b/${1#dir-a/}
— путь к соответствующему каталогу вdir-b
.
Если каталог из dir-a
не существует в dir-b
, вы получите сообщение об ошибке от diff
, что позволяет вам быстро определить несоответствия.
Другие способы ограничения глубины
Если ваш find
не поддерживает -maxdepth
, вы можете использовать другой подход с помощью параметров -path
и -prune
. Например, для ограничения глубины до 2-ух уровней можно использовать:
find dir-a -path '*/' -prune -o -type d -exec sh -c 'diff "$1" "dir-b/${1#dir-a/}"' sh {} \;
Заключение
Использование команды find
в сочетании с diff
позволяет элегантно решить задачу сравнения каталогов до определенной глубины, избегая циклов и дополнительных скриптов. Такой подход обеспечивает не только гибкость в выборе глубины, но и улучшает читаемость и производительность ваших командных операций.
Если у вас есть дополнительные вопросы по данному процессу, не стесняйтесь обращаться за помощью!