/ / Изтриване на файлове в една директория, които не съществуват в друга директория или нейните подчинени директории - linux, shell, unix, scripting

Изтриване на файлове в една директория, които не съществуват в друга директория или нейните подчинени директории - 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 + shell, може да се използва 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 shell която позволява на скрипта да изпълни basename без допълнителен процес (по име на файл). Това прави скрипта по-бърз.
  • done < <(find $2 -type f) е баш функция което позволява на скрипта да прочете списъка с имена на файлове от 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