Аз съм все още начинаещ в скрипт черупки и се опитва да излезе с един прост код. Може ли някой да ми даде някаква посока тук. Ето какво ми трябва.
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