Если вам не нужно знать, какие части файлов отличаются, вы можете использовать контрольную сумму файла. Существует много способов сделать это, используя md5sum или sha256sum. В принципе, каждый из них выводит строку, в которую помещается содержимое хэша. Если оба файла одинаковы, их хэш будет таким же. Это часто используется при загрузке программного обеспечения, например, в Ubuntu. Они часто используются для проверки целостности загруженного контента.
Рассмотрим сценарий ниже, где вы можете дать два файла в качестве аргументов, и файл скажет вам, являются ли они одинаковыми или нет. [!d2 ]
#!/bin/bash
# Check if both files exist
if ! [ -e "$1" ];
then
printf "%s doesn't exist\n" "$1"
exit 2
elif ! [ -e "$2" ]
then
printf "%s doesn't exist\n" "$2"
exit 2
fi
# Get checksums of eithe file
file1_sha=$( sha256sum "$1" | awk '{print $1}')
file2_sha=$( sha256sum "$2" | awk '{print $1}')
# Compare the checksums
if [ "x$file1_sha" = "x$file2_sha" ]
then
printf "Files %s and %s are the same\n" "$1" "$2"
exit 0
else
printf "Files %s and %s are different\n" "$1" "$2"
exit 1
fi
Пример прогона:
$ ./compare_files.sh /etc/passwd ./passwd_copy.txt
Files /etc/passwd and ./passwd_copy.txt are the same
$ echo $?
0
$ ./compare_files.sh /etc/passwd /etc/default/grub
Files /etc/passwd and /etc/default/grub are different
$ echo $?
1
Кроме того, есть команда comm, которая сравнивает два отсортированных файла и дает результат в 3-х столбцах : столбец 1 для элементов, уникальных для файла # 1, столбец 2 для элементов, уникальных для файла # 2, и столбца 3 для элементов, присутствующих в обоих файлах.
Чтобы подавить любой столбец, вы можете использовать переключатели -1, -2 и -3.
Ниже вы можете увидеть скриншот команды в действии.
Существует только одно требование: файлы должны быть отсортированы для правильной их сопоставления. Для этой цели может использоваться команда sort. Bellow - это еще один снимок экрана, где файлы сортируются, а затем сравниваются. Строки, начинающиеся с левого звонка только в File_1, строки, начинающиеся с столбца 2, принадлежат только File_2
Как вы уже узнали, вы можете использовать функцию extglob, которая включена с помощью:
shopt -s extglob
Это позволяет исключить совпадения, чтобы вы могли делать такие вещи, как:
rm 100/!([ab].txt) 101/!([cd].txt)
Рекомендуется сначала проверить его с помощью echo. Этот пример будет соответствовать чему-либо внутри 100/, который не является a.txt или b.txt и чем-либо внутри 101/, который не является c.txt или d.txt. Если к 102/ применяются те же правила для 100/, вы можете сделать, например ::!!d2]
10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)
Как вы уже узнали, вы можете использовать функцию extglob, которая включена с помощью:
shopt -s extglob
Это позволяет исключить совпадения, чтобы вы могли делать такие вещи, как:
rm 100/!([ab].txt) 101/!([cd].txt)
Рекомендуется сначала проверить его с помощью echo. Этот пример будет соответствовать чему-либо внутри 100/, который не является a.txt или b.txt и чем-либо внутри 101/, который не является c.txt или d.txt. Если к 102/ применяются те же правила для 100/, вы можете сделать, например ::!!d2] 10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)
Как вы уже узнали, вы можете использовать функцию extglob, которая включена с помощью:
shopt -s extglob
Это позволяет исключить совпадения, чтобы вы могли делать такие вещи, как:
rm 100/!([ab].txt) 101/!([cd].txt)
Рекомендуется сначала проверить его с помощью echo. Этот пример будет соответствовать чему-либо внутри 100/, который не является a.txt или b.txt и чем-либо внутри 101/, который не является c.txt или d.txt. Если к 102/ применяются те же правила для 100/, вы можете сделать, например ::!!d2] 10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)
Вы можете использовать find для этого. Вы можете отрицать тесты в find с помощью -not или !. Это будет исключать совпадения, а не находить их.
Вы должны быть осторожны, чтобы не удалять ни один из родительских каталогов файлов, которые вы хотите сохранить, особенно в текущем каталоге ., поэтому убедитесь, что вы читаете вывода до удаления.
На основе вашего примера вы можете сделать что-то подобное из каталога data.
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"
Добавьте ! -path ./path/to/dir для любого пути, который вы хотите избежать удаления. Вы можете использовать метасимволы, такие как *, но убедитесь, что вы указываете это выражение, например "./path*dir", чтобы предотвратить любые нежелательные расширения.
find по умолчанию рекурсивный. Даже если мы не найдем здесь ./100, мы найдем все его содержимое, если они не совпадут с рисунком [ab].txt. Если вы не можете сопоставить все имена, которые хотите сохранить, добавьте еще один тест:
! -path "./100/[ab].txt" ! -path ./100/foo
Это не обнаружит a.txt или b.txt или foo, но он найдет все другие файлы.
Когда вы уверены, что видите, что хотите, вы можете добавить -delete в конец, чтобы удалить найденные файлы:
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete
Вы можете использовать find для этого. Вы можете отрицать тесты в find с помощью -not или !. Это будет исключать совпадения, а не находить их.
Вы должны быть осторожны, чтобы не удалять ни один из родительских каталогов файлов, которые вы хотите сохранить, особенно в текущем каталоге ., поэтому убедитесь, что вы читаете вывода до удаления.
На основе вашего примера вы можете сделать что-то подобное из каталога data.
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"
Добавьте ! -path ./path/to/dir для любого пути, который вы хотите избежать удаления. Вы можете использовать метасимволы, такие как *, но убедитесь, что вы указываете это выражение, например "./path*dir", чтобы предотвратить любые нежелательные расширения.
find по умолчанию рекурсивный. Даже если мы не найдем здесь ./100, мы найдем все его содержимое, если они не совпадут с рисунком [ab].txt. Если вы не можете сопоставить все имена, которые хотите сохранить, добавьте еще один тест:
! -path "./100/[ab].txt" ! -path ./100/foo
Это не обнаружит a.txt или b.txt или foo, но он найдет все другие файлы.
Когда вы уверены, что видите, что хотите, вы можете добавить -delete в конец, чтобы удалить найденные файлы:
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete
Вы можете использовать find для этого. Вы можете отрицать тесты в find с помощью -not или !. Это будет исключать совпадения, а не находить их.
Вы должны быть осторожны, чтобы не удалять ни один из родительских каталогов файлов, которые вы хотите сохранить, особенно в текущем каталоге ., поэтому убедитесь, что вы читаете вывода до удаления.
На основе вашего примера вы можете сделать что-то подобное из каталога data.
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"
Добавьте ! -path ./path/to/dir для любого пути, который вы хотите избежать удаления. Вы можете использовать метасимволы, такие как *, но убедитесь, что вы указываете это выражение, например "./path*dir", чтобы предотвратить любые нежелательные расширения.
find по умолчанию рекурсивный. Даже если мы не найдем здесь ./100, мы найдем все его содержимое, если они не совпадут с рисунком [ab].txt. Если вы не можете сопоставить все имена, которые хотите сохранить, добавьте еще один тест:
! -path "./100/[ab].txt" ! -path ./100/foo
Это не обнаружит a.txt или b.txt или foo, но он найдет все другие файлы.
Когда вы уверены, что видите, что хотите, вы можете добавить -delete в конец, чтобы удалить найденные файлы:
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete