Исключение определенных файлов и каталогов при удалении файлов

Дополнительный ответ

Если вам не нужно знать, какие части файлов отличаются, вы можете использовать контрольную сумму файла. Существует много способов сделать это, используя 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

enter image description here

11
задан 2 January 2018 в 17:27

6 ответов

Как вы уже узнали, вы можете использовать функцию 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)
10
ответ дан 22 May 2018 в 15:48
  • 1
    Я просто привел пример для 100 и 101 каталогов, но на самом деле количество подкаталогов составляет около 20. Есть ли способ реализовать выше код для каждого каталога без записи каждого имени каталога в основной папке? – deepblue 2 January 2018 в 17:11
  • 2
    @deepblue Пожалуйста, укажите точный пример этого вопроса ( edit ), особенно неясно, как rm должен знать, какие файлы хранить в каталогах, если вы не хотите их указывать. – dessert 2 January 2018 в 17:13

Как вы уже узнали, вы можете использовать функцию 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)

10
ответ дан 18 July 2018 в 00:02

Как вы уже узнали, вы можете использовать функцию 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)

10
ответ дан 24 July 2018 в 17:09

Вы можете использовать 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
6
ответ дан 22 May 2018 в 15:48

Вы можете использовать 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
6
ответ дан 18 July 2018 в 00:02

Вы можете использовать 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
6
ответ дан 24 July 2018 в 17:09

Другие вопросы по тегам:

Похожие вопросы: