У меня есть два каталога и мне нужно вывести их различия в этом формате
пример :
DIR1 conatins : file1
file2
file3
DIR2 contains : file1
file4
Вывод (только имена файлов, без содержимого файлов): файл 1 изменен или тот же, файл 2 удален, файл 4 добавлен
решение1
Это просто, ознакомьтесь с популярным инструментом diff
:
diff -r dir1 dir2
Редактировать: Я неправильно понял вопрос OP, чтобы получить только информациючтофайлы отличаются, некакони отличаются, вам необходимо использовать -q
опцию:
diff -r -q dir1 dir2
решение2
Эмулируем, как такие инструменты, как comm
или join
, сравнивают два набора отсортированных входных данных, используя bash
:
# Get lists of (base-)names from both directories.
files1=( dir1/* ); files1=( "${files1[@]##*/}" )
files2=( dir2/* ); files2=( "${files2[@]##*/}" )
# Loop over these sorted lists until one of them is empty.
while [[ ${#files1[@]} -gt 0 ]] && [[ ${#files2[@]} -gt 0 ]]; do
name1=${files1[0]}
name2=${files2[0]}
if [[ $name1 == "$name2" ]]; then
# Name exists in both directories.
printf '%s is modified or same\n' "$name1"
files1=( "${files1[@]:1}" )
files2=( "${files2[@]:1}" )
elif [[ $name1 < $name2 ]]; then
# Name exists in only first directory.
printf '%s is removed\n' "$name1"
files1=( "${files1[@]:1}" )
else
# Name exists in only second directory.
printf '%s is added\n' "$name2"
files2=( "${files2[@]:1}" )
fi
done
# Handle remaining names.
if [[ ${#files1[@]} -gt 0 ]]; then
printf '%s is removed\n' "${files1[@]}"
fi
if [[ ${#files2[@]} -gt 0 ]]; then
printf '%s is added\n' "${files2[@]}"
fi
Я использую два bash
массива для хранения имен, найденных в каждом каталоге, а затем повторяю цикл до тех пор, пока один из этих массивов не станет пустым.
В цикле я сравниваю первое имя каждого массива друг с другом. Если имена совпадают, то файл тот же самый или, возможно, был изменен (тогда имя удаляется из обоих массивов).
Если имя из первого массива сортируется перед именем из второго массива (проверено с помощью <
), то первое имя отсутствует во втором каталоге. Теперь удалите первый элемент первого массива.
В противном случае имя из второго массива отсутствует в первом каталоге. Теперь удалите первый элемент второго массива.
После цикла один из массивов все еще может быть непустым, поэтому при необходимости выведите имена из этого массива.