Я все ще новачок у сценаріях оболонки і намагаюся придумати простий код. Хтось міг би дати мені якийсь напрямок тут. Ось що мені потрібно.
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
без призначення розподілу масивуу підпроцесі. Тут причина використання функції полягає в тому, що якщо масив оновлюється в підпроцесі, це не матиме впливу на значення масиву в сценарії, яке передається другому циклу.
Для відповідного обговорення:
- Витяг базового імені файлу без шляху та розширення в Bash
- Сценарій Bash: Дилема підкладової оболонки While-Loop
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