/ / Usuń pliki w jednym katalogu, które nie istnieją w innym katalogu lub jego katalogach podrzędnych - linux, shell, unix, scripting

Usuń pliki w jednym katalogu, które nie istnieją w innym katalogu lub jego katalogach podrzędnych - linux, shell, unix, scripting

Wciąż jestem nowicjuszem w skryptowaniu powłoki i próbuję wymyślić prosty kod. Czy ktokolwiek mógłby mi tutaj podać jakiś kierunek. Oto, czego potrzebuję.

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

Teraz muszę usunąć plik 300ijkl w / tmp jakoodpowiedni plik kopii zapasowej nie jest obecny w / home / storage. Plik / tmp zawiera ponad 300 plików. Muszę usunąć pliki w / tmp, dla których nie ma odpowiednich plików kopii zapasowych, a nazwy plików w / tmp będą pasować do nazw plików w / home / storage lub katalogach w / home / storage.

Doceń swój czas i odpowiedź.

Odpowiedzi:

0 dla odpowiedzi № 1

Możesz rozwiązać to przez

  • tworzenie listy plików w /home/storage
  • testowanie każdej nazwy pliku /tmp aby zobaczyć, czy jest na liście /home/storage

Biorąc pod uwagę znaczniki powłoki linux +, można użyć bash:

  • zrób listę plików z /home/storage na tablica asocjacyjna
  • uczynić z indeksu tablicy nazwę pliku

Oto przykładowy skrypt do zilustrowania ($1 i $2 są parametrami, które należy przekazać do skryptu, tj. /home/storage i /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)

Wykorzystuje dwie interesujące funkcje powłoki:

  • name=${path##*/} jest Powłoka POSIX funkcja, która umożliwia wykonanie skryptu basename funkcja bez dodatkowego procesu (na nazwę pliku). To sprawia, że ​​skrypt jest szybszy.
  • done < <(find $2 -type f) jest funkcja bash co pozwala skryptowi odczytać listę nazw plików z find bez wykonywania przypisań do tablicyw podprocesie. Powodem użycia tej funkcji jest to, że jeśli tablica jest aktualizowana w podprocesie, nie ma to wpływu na wartość tablicy w skrypcie przekazywanym do drugiej pętli.

Dla powiązanej dyskusji:


0 dla odpowiedzi nr 2

Możesz również podejść do usuwania za pomocą grep także. Możesz zapętlić pliki w /tmp sprawdzanie za pomocą ls podłączony do grepi usuwanie, jeśli nie ma dopasowania:

#!/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

Uwaga: faktyczne usunięcie zostało skomentowane powyżej, przetestuj i upewnij się, że nie ma żadnych niezamierzonych konsekwencji przed utworzeniem faktycznego usunięcia. Nazwij to przechodząc ścieżką do tmp (bez ciągnięcia /) jako pierwszy argument iz /home/storage jako drugi argument:

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