Mam dwa foldery o podobnych strukturach podfolderów, które chciałbym porównać. Na przykład:
A
├── child-1
├── child-2
├── child-3
├── child-4
├── child-5
i
B
├── child-1-some-text
├── child-2-more-text
├── child-3-nothing
├── child-6-random-text
├── child-7-more-random-text
Chciałbym wymienić wszystkie te podfoldery, z A
których są prefiksy dla podfolderu, B
oraz wymienić odpowiednie podfoldery B
. Oczekiwany wynik to
child-1 -- child-1-some-text
child-2 -- child-2-more-text
child-3 -- child-3-nothing
Drugie wymaganie: jeśli wiele pasuje B
, to powinno dać błąd / ostrzeżenie.
Moje rozwiązanie :
cd A
for f in `ls -d */`;
do
cd B;
new_dirs=(`ls -1d $f*`);
cd -;
if [ ${#new_dirs[@]} -eq 0 ]
then
## DO_Nothing
continue;
elif [ ${#new_dirs[@]} -gt 1 ]
then
echo "Multiple matches to $f";
continue;
else
echo "Unique Match found to $f -- ${new_dirs[0]}";
continue;
fi;
done
Problem:
Dla tych wartości $f
, które nie mają odpowiednich podfolderów B
, konstrukcja tablicy daje mi błąd. na przykład:
ls: nie można uzyskać dostępu do „child-4 *”: nie ma takiego pliku ani katalogu
Pytanie
- Jak pozbyć się tych błędów?
- Czy istnieje lepszy sposób na osiągnięcie celów niż ten w moim kodzie?
Z góry dziękuję!
diff -rq DIR1 DIR2
do porównania nie tylko struktury katalogów, ale zawartości pliku.Odpowiedzi:
Lepszy sposób
Nie parsuj
ls
; zamiast tego użyj globów. W rzeczywistości już używasz globów, po prostu je pakujeszls
, co jest bezcelowe. Musisz tylkonullglob
włączyć, gdy nie ma żadnych dopasowań.Również unikanie
cd
upraszcza rzeczy.Wynik:
Dodałem,
B/child-3-something
aby przetestować wymaganie wtórne. To tworzy strukturę katalogów do testowania:Nawiasem mówiąc, ShellCheck jest bardzo przydatny do znajdowania problemów w skryptach powłoki.
źródło
shellcheck
pakietu byłaby najbezpieczniejsza]ShellCheck
. Uwielbiam tę część, w której nie tylko mówi o twoich błędach, ale także daje sugestie! @ Xen2050, o części przesyłania, po prostu zainstalowanyshellcheck
przy użyciuapt
, a następnie sieć niepełnosprawnej. Wygląda na to, że działa bez internetu .Wywołanie
ls
nieistniejącego folderu powoduje wyświetlenie komunikatu o błędzie. Prosty sposób, aby po prostu zignorować to poprzez zastąpienie linii 5 w skrypcie z tym:new_dirs=(`ls -1d $f* 2> /dev/null`);
.źródło
t=(`echo ok; echo err 1>&2`)
$ t (lub${t[@]}
) zawiera tylko ok, err jest widoczny w terminalu, ale i tak nie jest zapisywany. Czy jest coś śmiesznego w moim teście?