/ / Видалити файли в одному каталозі, яких немає в іншому каталозі або його дочірніх каталогах - linux, shell, unix, сценарії

Видалити файли в одному каталозі, які не існують в іншому каталозі або його дитячих каталогах - linux, shell, unix, scripting

Я все ще новачок у сценаріях оболонки і намагаюся придумати простий код. Хтось міг би дати мені якийсь напрямок тут. Ось що мені потрібно.

Files in path 1: /tmp
100abcd
200efgh
300ijkl

Files in path2: /home/storage
backupfile_100abcd_str1
backupfile_100abcd_str2
backupfile_200efgh_str1
backupfile_200efgh_str2
backupfile_200efgh_str3

Тепер мені потрібно видалити файл 300ijkl в / tmp яквідповідний файл резервної копії відсутній у / home / storage. Файл / tmp містить більше 300 файлів. Мені потрібно видалити файли в / tmp, для яких відсутні відповідні файли резервних копій, а імена файлів у / tmp будуть відповідати іменам файлів у / home / storage або каталогах у / home / storage.

Цінуйте свій час і відповідь.

Відповіді:

0 для відповіді № 1

Ви можете вирішити це

  • створення списку файлів у /home/storage
  • тестування кожного імені файлу в /tmp щоб перевірити, чи є це у списку від /home/storage

Враховуючи теги оболонки linux +, можна використовувати bash:

  • скласти список файлів з /home/storage ан асоціативний масив
  • зробити індекс масиву ім'ям файлу

Ось зразок сценарію для ілюстрації ($1 і $2 - це параметри, що передаються сценарію, тобто /home/storage і /tmp):

#!/bin/bash
declare -A InTarget

while read path
do
name=${path##*/}
InTarget[$name]=$path
done < <(find $1 -type f)

while read path
do
name=${path##*/}
[[ -z ${InTarget[$name]} ]] && rm -f $path
done < <(find $2 -type f)

Він використовує дві цікаві функції оболонки:

  • name=${path##*/} це Оболонка POSIX функція, яка дозволяє сценарію виконувати basename функція без зайвого процесу (на ім'я файлу). Це робить сценарій швидшим.
  • done < <(find $2 -type f) це функція bash що дозволяє сценарію читати список назв файлів find без призначення розподілу масивуу підпроцесі. Тут причина використання функції полягає в тому, що якщо масив оновлюється в підпроцесі, це не матиме впливу на значення масиву в сценарії, яке передається другому циклу.

Для відповідного обговорення:


0 для відповіді № 2

Ви також можете підійти до видалення за допомогою grep так само. Ви можете цикл, хоча файли в /tmp перевірка с ls трубопровід до grepта видалення, якщо немає відповідності:

#!/bin/bash

[ -z "$1" -o -z "$2" ] && {  ## validate input
printf "error: insufficient input. Usage: %s tmpfiles storagen" ${0//*//}
exit 1
}

for i in "$1"/*; do
fn=${i##*/}  ## strip path, leaving filename only

## if file in backup matches filename, skip rest of loop
ls ${2}* | grep -q $fn &>/dev/null && continue

printf "removing %sn" "$i"
# rm "$i" ## remove file
done

Примітка: фактичне видалення коментується вище, протестуйте та переконайтеся, що немає жодних ненавмисних наслідків перед тим, як зробити фактичне видалення. Назвіть це проходженням шляху до tmp (без відставання /) як перший аргумент і с /home/storage як другий аргумент:

$ bash scriptname /path/to/tmp /home/storage